这是我几天前刚刚开始引起StackOverflow异常的有点复杂的设置:
在我的基于Windows的持续集成平台上,我有一个启动Python脚本的Jenkins作业。 这个Python脚本运行一个cmake命令,一个msbuild调用,然后执行新编译的基于gtest的测试框架。 msbuild生成一个dll和gtest可执行文件。然后可执行文件本身加载dll以进行测试。
几天前,我在dll的源代码中做了一些更改,这些更改改变了我的一些结构的内存占用(基本上只是数组长度)。它是普通的C代码。现在,一些测试以堆栈溢出异常退出。
我承认我在堆栈上放置了一些不一定必须存在的数据结构,但它是我在C中隐藏信息的最好结果(优于C)使用静态全局变量)。
if(myCondition)
{
int hugeBuffer[20000];
...
}
除此之外,没有任何递归或任何花哨的事情可能是麻烦的合法来源。大块数据总是通过引用(指针)传递。
无论如何,直接从Visual Studio运行gtest可执行文件的本地机器上不会发生堆栈溢出异常,除非我在链接器设置中显着减少了保留的堆栈内存。 然后在调试模式下,我明显地遇到了一个堆栈刚刚在函数开头溢出的点。 不幸的是,我无法找到任何方法来调试堆栈的完整程度。在VS中,我只得到了一个没有显示当前"填充水平的呼叫堆栈窗口"堆栈。
因此,虽然你们可能会为此杀死mir,但我猜测我在运行Jenkins工作时确实没有足够的堆栈内存可用。 所以我想知道什么步骤实际定义了我的DLL代码可用的堆栈内存量。它明显低于我本地计算机上VisualStudio中默认的10MB。
在msbuild步骤中没有用于链接器的STACK参数,因此我猜测exe标头应该包含与Visual Studio中相同的值(10MB?)。 Python脚本运行subprocess.call,它可以忽略链接器设置的值并覆盖它。我既没有找到任何关于该信息的信息,也没有找到如何更改分配的堆栈内存。我甚至不知道它是否会产生一个线程或一个可能also affect the stack size的进程。 Windows中的DLL加载机制对我来说也有些神秘,但我猜测dll使用与使用它的可执行文件相同的堆栈。我使用WinBase.h中的LoadLibrary()宏。
答案 0 :(得分:0)
纯粹的运气我发现尽管使用相同的CMakeLists.txt来创建项目(本地和Jenkins),但由它们生成的结果项目会有所不同。
我的本地项目(以及我在服务器上手动创建的用于错误查找的GUI-VisualStudio解决方案)保留了10MB的堆栈,而基于python的CMake调用仅使用默认值1MB,这对于项目
可以通过将此行添加到CMakeLists.txt来补偿Cmake的这种奇怪行为:
# Set linker to use 10MB of stack memory for all gtest executables, the default of 1MB is not enough!
SET( CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /STACK:\"10000000\"")
抱歉打扰你:)
我很高兴它结束了