我正在尝试使用 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
就没有明显的问题。但是,此问题将 10 分钟的构建变成了一个多小时的构建。
此问题在 XP x86 计算机上不存在,我还没有研究过这两个操作系统的 x64。
有人在 Windows 7 上使用 ccppc 或其他 gcc 二进制文件遇到过类似的问题吗?任何寻找解决方案的指导都会很棒。
最佳答案
从 Windows XP 32 位下编译到 Windows 7 64 位下时,发现 gcc 2.96 for PowerPC 中的 cc1.exe 程序失败,并在某些编译中出现相同的错误。使用 Visual Studio 调试器附加到 cc1.exe 并使用 Sysinternals 工具进行监视的调查显示:
当 cc1.exe 程序成功时,它会生成 3 个线程。
当 cc1.exe 程序失败时,第三次 CreateThread() 调用失败,并显示
ERROR_NOT_ENOUGH_MEMORY
.cc1.exe 的镜像 header ,通过运行 Visual Studio 报告
dumpbin /HEADERS
命令,显示堆栈保留大小为 400000000 字节。即创建的每个线程需要 400000000 字节的连续虚拟地址空间。当 CreateThread 调用失败并显示
ERROR_NOT_ENOUGH_MEMORY
时,Sysinternals VMMap 工具显示最大可用虚拟内存区域小于请求的堆栈保留大小 400000000 字节。cc1.exe 是一个 32 位进程,具有 2G 字节的虚拟地址空间。 Windows 7具有ASLR(地址空间布局随机化),这会导致DLL的加载地址被随机化。我认为 ASLR 有效地对虚拟地址空间进行了碎片化,这样在 cc1.exe 进程的某些调用中,加载的 DLL 使用的虚拟地址不会为线程堆栈留下足够大的可用区域。除了 ASLR 之外,在 Windows 7 中,加载到 cc1.exe 中的 DLL 大约是 Windows XP 下的 4 倍,这可能是导致该问题的原因。
根据上述调查,Visual Studio editbin /STACK:67108864
程序用于将 cc1.exe 的堆栈保留大小减少到 64Mbytes,其中选择 64Mbytes 是因为这是用于 C++ 代码的 cc1plus.exe 程序的堆栈保留大小。随着堆栈保留大小的减少ERROR_NOT_ENOUGH_MEMORY
没有再出现错误。
关于gcc - 在 Windows 7 x86 上进行 ccppc 编译期间出现 Win32 错误 8,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14840572/