1

我正在尝试使用 ccppc(版本 3.3-e500)编译一些 C 源文件。大多数情况下,编译会失败,请注意以下错误

0 [main] cc1 {PID} sigproc_init: cannot create wait_sig thread, Win32 Error 8

我查了这个 Win32 错误,它对应于ERROR_NOT_ENOUGH_MEMORY. 我很确定这不是物理内存的问题,我在这台机器上有 4GB,编译时使用的内存不超过 1.5GB。不幸的是,我的机器上没有本地管理员,因此无法调查页面文件的问题。

.o几次失败后,源代码最终会编译,一旦所有源代码都编译完成,输出的 's没有明显问题。但是,这个问题将 10 分钟的构建变成了一个多小时的构建。

这个问题在 XP x86 机器上不存在,我没有研究过 x64 的任何一个操作系统。

有没有人在 Windows 7 上使用 ccppc 或其他 gcc 二进制文件遇到过这样的问题?寻找解决方案的任何指导都会很棒。

4

2 回答 2

2

从在 Windows XP 32 位下编译到 Windows 7 64 位下编译时,发现 PowerPC 的 gcc 2.96 中的 cc1.exe 程序在某些编译时失败并出现相同的错误。使用 Visual Studio 调试器附加到 cc1.exe 并使用 Sysinternals 工具进行监视的调查表明:

  1. 当 cc1.exe 程序成功时,它会产生 3 个线程。

  2. 当 cc1.exe 程序失败时,第 3 次 CreateThread() 调用失败并显示ERROR_NOT_ENOUGH_MEMORY.

  3. 运行 Visual Studio 命令报告的 cc1.exe 的图像标头dumpbin /HEADERS显示堆栈保留大小为 400000000 字节。即创建的每个线程需要 400000000 字节的连续虚拟地址空间。

  4. 当 CreateThread 调用失败时ERROR_NOT_ENOUGH_MEMORY,Sysinternals VMMap 工具显示最大可用虚拟内存区域小于请求的堆栈保留大小 400000000 字节。

  5. cc1.exe 是一个 32 位进程,它有 2GB 的虚拟地址空间。Windows 7 具有 ASLR(地址空间布局随机化),这会导致 DLL 的加载地址随机化。我认为 ASLR 有效地分割了虚拟地址空间,因此在 cc1.exe 进程的某些调用中,加载的 DLL 使用的虚拟地址不会为线程堆栈留下足够大的空闲区域。除了 ASLR,在 Windows 7 中加载到 cc1.exe 中的 DLL 大约是 Windows XP 下的 4 倍,这可能会导致该问题。

根据上述调查,使用 Visual Studioeditbin /STACK:67108864程序将 cc1.exe 的堆栈保留大小减少到 64Mbytes,其中选择 64Mbytes 作为用于 C++ 代码的 cc1plus.exe 程序的堆栈保留大小。随着堆栈保留大小的减少,ERROR_NOT_ENOUGH_MEMORY错误不再出现。

于 2015-12-11T10:41:33.963 回答
0

所以,我从来没有真正找到解决方案,但我确实设法想出了一个可行的解决方法。

由于编译最终将在多次重新之后工作make,您可以将您的make命令包装在一个检查“ERRORLEVEL”变量的do/while循环中,并继续直到它指示成功。

这显然不能解决“需要永远编译”的问题,但你的编译最终会成功。

于 2014-03-26T15:04:34.957 回答