【问题标题】:Strange error on in windows Shared memoryWindows共享内存中出现奇怪的错误
【发布时间】:2023-03-13 21:34:01
【问题描述】:

我正在用 c 创建一个 Web 服务器。我想要它是多进程的,所以我需要在进程之间共享一些东西。

我使用了共享内存,但有时我的进程因内存违规访问而崩溃。

共享内存的地址可能因进程而异。 gdb 调试似乎是不可能的(我也尝试过附加到正在运行的进程,但仍然没有多大成功)。

我从微软网站下载了示例代码,尝试运行它,发现每次运行时指向内存地址的指针都不一样。

我有一个主进程,每隔几毫秒检查一次是否有两个进程处于活动状态。每个进程服务一个客户端,然后死亡。

行为是这样的:有时,当我运行程序时,它在第一次尝试使用共享内存时崩溃。有时需要许多重新生成的进程才能使程序崩溃。只需一个生成的进程,它每次都运行良好。

实际上,这只是一个 Linux 服务器的移植程序,所以我不认为我在其他地方的指针做错了什么。

这是在主进程上创建内存映射的代码:

SECURITY_ATTRIBUTES security = { 
    sizeof(security), NULL, TRUE
};

hSharedMemory = CreateFileMapping(
             INVALID_HANDLE_VALUE,    // use paging file
             &security,               // Handle ereditabile
             PAGE_READWRITE| SEC_NOCACHE | SEC_COMMIT,          // read/write access
             0,                       // maximum object size (high-order DWORD)
             region_sz,               // maximum object size (low-order DWORD)
             NULL);                 // name of mapping object
if (hSharedMemory == NULL)
{
    printf("CreateFileMapping: %lu", GetLastError());
    exit(EXIT_FAILURE);
}

然后,我将把带有其他东西的 HANDLE 传递给使用 PIPE 生成的进程。

然后,它使用以下命令打开内存映射:

ptr = MapViewOfFile(hSharedMemory,   // handle to map object
                    FILE_MAP_ALL_ACCESS, // read/write permission
                    0,
                    0,
                    region_sz);

我已阅读 msdn 文档,但找不到任何想法为什么会发生这种情况。

在创建进程时,我已将句柄 inerithance 参数设置为 TRUE。

我使用的是带有 mingw 编译器的 Windows 8.1。

【问题讨论】:

  • 访问冲突可能是由代码中的错误引起的(99% 的可能性)。显示的代码是正确的,因此如果没有完整的重现,我们将无法为您提供帮助。
  • 我真的建议你让 gdb 工作或尝试 valgrind (valgrind --leak-check=yes --trace-children=yes)
  • @SimonMourier 是这么认为的,但正如我所说,这只是一个运行良好的 linux 程序的移植。所以我试图在两个项目的差异中找到错误。
  • @terencehill 在 Linux 上,我将 gdb 设置为设置 follow-fork-mode 子级。无论如何,当达到错误时,gdb dosent' 出于某种原因显示任何内容。由于 VisualStudio,我发现这是内存访问冲突(但没有更多帮助)。
  • 源码的哪一部分崩溃了?

标签: c windows memory shared-memory


【解决方案1】:

您不能只通过管道将句柄传递给其他进程。这不起作用。

来自MSDN:

多个进程可以通过使用单个共享文件映射对象或创建由同一文件支持的单独文件映射对象来共享同一文件的视图。 单个文件映射对象可以被多个进程共享,方法是在进程创建时继承句柄,复制句柄,或按名称打开文件映射对象。有关详细信息,请参阅 CreateProcess、DuplicateHandle 和 OpenFileMapping 函数。

也是一个很好的信息来源:MSDN on Inheritance。

我建议创建一个 guid 并将其用作 lpName 中的 CreateFileMapping 和 OpenFileMapping。

【讨论】:

  • 谢谢。请参阅我的编辑:在进程创建时,我已将句柄 inerithance 参数设置为 TRUE。所以还不够吗?还是我需要复制句柄?
  • 另外,我已经尝试过这种方式。在 Windows 7 中,每次我想调试我的程序时,我都需要管理员权限才能运行该程序,但无论如何都会崩溃。
  • @FedericoPonzi 应该够了,不需要复制句柄。
  • 所以我只需要使用管道将句柄值发送到子进程吗?
  • @FedericoPonzi 是的,这就是我阅读 MSDN 关于继承的文章的方式。
猜你喜欢
  • 1970-01-01
  • 2021-04-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-04-01
  • 2010-11-07
  • 2015-11-13
相关资源
最近更新 更多