如何在 Python 中更改子进程的堆栈大小

How to change the stack size of subprocess in Python

这是我几天前刚刚开始导致 Whosebug 异常的有点复杂的设置:

在我的 windows-based 持续集成平台上,我有一个启动 Python 脚本的 Jenkins 作业。 这个 Python 脚本 运行 是一个 cmake 命令,一个 msbuild 调用,然后执行新编译的 gtest-based 测试框架。 msbuild 生成一个 dll 和 gtest 可执行文件。然后可执行文件本身加载 dll 以对其进行测试。

几天前,我对 dll 的源代码进行了一些更改,这些更改改变了我的某些结构(基本上只是数组长度)的内存占用。这是纯 C 代码。现在一些测试以 stack-overflow 异常退出。

我承认我在堆栈上放置了一些不一定必须存在的数据结构,但这是我在 C 中隐藏信息的最佳方法(比使用静态全局变量更好)。

if(myCondition)
{
    int hugeBuffer[20000];
    ...
}

除此之外,没有递归或任何可能成为合法麻烦源的奇特行为。大块数据总是通过引用(指针)传递。

无论如何,堆栈溢出异常不会在我的本地计算机上发生 运行直接从 Visual Studio 中运行 gtest 可执行文件,除非我显着减少链接器设置中保留的堆栈内存。 然后在调试模式下,我清楚地 运行 进入一个堆栈刚好在函数开头溢出的点。 不幸的是,我找不到任何调试堆栈有多满的方法。在 VS 中,我只有调用堆栈 window,它不显示堆栈的当前 "fill level"。

因此,尽管你们可能会为此而杀死 mir,但我猜我在 运行 执行 Jenkins 作业时确实没有足够的可用堆栈内存。 所以我想知道哪一步实际定义了可用于我的 DLL 代码的堆栈内存量。它显然小于我在本地计算机上的 VisualStudio 中的默认 10MB。

在 msbuild 步骤中,链接器没有使用 STACK 参数,所以我猜测 exe header 应该包含与 Visual Studio 中相同的值(10MB?)。 Python 脚本 运行 是一个 subprocess.call ,它可以忽略链接器设置的值并覆盖它。我既找不到关于它的任何信息,也找不到关于如何更改分配的堆栈内存的信息。我什至不知道它是否会产生一个线程或一个可能 also affect the stack size 的进程。 windows 中的 DLL 加载机制对我来说也有些神秘,但我猜测 dll 使用与使用它的可执行文件相同的堆栈。我正在使用 WinBase.h.

中的 LoadLibrary() 宏

幸运的是,我发现虽然相同的 CMakeLists.txt 用于创建项目(本地和 Jenkins),但它们生成的结果项目不同。

我的本地项目(以及我在服务器上手动创建的用于错误查找的 GUI-VisualStudio 解决方案)保留了 10MB 的堆栈,而基于 python 的 CMake 调用仅使用默认值 1MB这对项目来说还不够。

Cmake 的这种奇怪行为可以通过将此行添加到 CMakeLists.txt 来补偿:

# 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\"")

抱歉打扰了:) 我很高兴它结束了