我正在尝试使用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二进制文件遇到这样的问题?找到解决方案的任何指导都很棒。
答案 0 :(得分:2)
从Windows XP 32位编译转移到Windows 7 64位时,发现来自GPC 2.96 for PowerPC的cc1.exe程序在某些编译时失败并出现相同的错误。使用Visual Studio调试器附加到cc1.exe并使用Sysinternals工具进行监视的调查显示:
当cc1.exe程序成功时,它会产生3个线程。
当cc1.exe程序失败时,第3次CreateThread()调用失败并显示ERROR_NOT_ENOUGH_MEMORY
。
通过运行Visual Studio dumpbin /HEADERS
命令报告的cc1.exe的映像头显示堆栈保留大小为400000000字节。即每个创建的线程需要400000000字节的连续虚拟地址空间。
当CreateThread调用失败并显示ERROR_NOT_ENOUGH_MEMORY
时,Sysinternals VMMap工具显示最大可用虚拟内存区域小于请求的堆栈保留大小400000000字节。
cc1.exe是一个32位进程,具有2 GB的虚拟地址空间。 Windows 7具有ASLR(地址空间布局随机化),这会导致DLL的加载地址被随机化。我认为ASLR实际上是对虚拟地址空间进行分段,因此在cc1.exe进程的某些调用中,加载的DLL使用的虚拟地址不会为线程堆栈留下足够大的空闲区域。与ASLR一样,在Windows 7中,与Windows XP相比,加载到cc1.exe中的DLL大约多4倍,这可能导致问题。
根据上述调查,Visual Studio editbin /STACK:67108864
程序用于将cc1.exe的堆栈保留大小减少到64Mbytes,其中选择了64Mbytes,因为这是cc1plus.exe程序的堆栈保留大小用于C ++代码。随着堆栈保留大小的减少,再次看不到ERROR_NOT_ENOUGH_MEMORY
错误。
答案 1 :(得分:0)
所以,我从未真正找到解决方案,但我确实设法提出了一个可行的解决方法。
由于编译最终会在多次重新make
之后运行,因此您可以将make
命令包装在检查'ERRORLEVEL'变量的do / while循环中,并继续执行直到它指示成功。
这显然无法解决“需要永远编译”的问题,但您的编译最终会成功。