如何在visualc++中快速检测导致堆栈溢出的函数

How to detect the one function causing a stack overflow quickly in Visual C++?

本文关键字:堆栈 栈溢出 函数 检测 visualc++      更新时间:2023-10-16

我有一个巨大的c++代码库。在某个数据集上存在堆栈溢出。如果我在Visual Studio调试器下运行程序,我会得到一个调用堆栈30个不熟悉的函数深度-其中一个(或多个)函数在堆栈上创建了一个太大的对象,这导致堆栈耗尽。我看了所有的函数,没有什么明显的——没有像

这样的
char buffer[512 * 1024];

我想我可以在每个函数的开头添加一个变量,并转储该变量地址,然后重新编译,然后查看相邻函数之间的差异,但这是大量的体力劳动。

如何快速识别在堆栈上创建了太大的对象集并导致缓冲区溢出的函数?

您可以在Visual c++中使用代码分析,它在更高版本中可用。如果函数使用的堆栈高于某个限制,则生成警告(C6262)。您可以使用/analyze:stacksize开关,其中stacksize是您想要的限制。

如果您有堆栈跟踪(并且您应该能够获得堆栈跟踪),您可能能够访问帧的地址。

引起问题的一个函数应该导致帧指针的巨大飞跃。

如果没有,检查堆栈大小,可能只是太小了。

EDIT:如何调试vc++中不明显的问题?(哼…Unix上的代码:/)

Elan Rusking在2011年的GDC演讲中做了一个关于调查的精彩演讲。

堆栈指针(在x86上)存储在ESP寄存器中。如果您查看一下反汇编并检查ESP的更改,那么您应该能够看到哪个函数使用较大的值对其进行了递增/递减操作。

维基百科上的例子:

mov eax, DWORD PTR SS:[esp]
add esp, 4

这个add esp就是你想要跟踪的。除非您使用vla,否则添加/减去的值是硬编码的,因此很容易检查。

线程超过其堆栈分配将引发异常。这个异常可以被microsoftvisualc++中的__try__except关键字捕获。你可以把你的函数包装在这个try-except块中,看看它们是否会导致堆栈溢出。

看这里:如何在Visual c++应用程序中捕获堆栈溢出