如何在 Visual C 中快速检测导致堆栈溢出的某个函数?
我有一个巨大的 C++ 代码库。在某些数据集上存在堆栈溢出。如果我在 Visual Studio 调试器下运行该程序,我会得到一个调用堆栈,其中有 30 个不熟悉的函数深 - 其中一个(或多个)函数在堆栈上创建了太大的对象,这导致堆栈耗尽。我查看了所有函数,没有什么明显的东西 - 没有什么像
char buffer[512 * 1024];
我一样,虽然我可以在每个函数的开头添加一个变量并转储该变量地址并重新编译,然后查看相邻函数之间的差异,但这是大量的体力劳动。
如何快速识别在堆栈上创建过多对象并导致缓冲区溢出的函数?
I have a huge C++ codebase. On a certain set of data there's a stack overflow. If I run the program under Visual Studio debugger I get a call stack 30 unfamiliar functions deep - one (or more) of those functions created a too big object on stack and this lead to stack exhaustion. I looked at all functions and there's nothing obvious - nothing like
char buffer[512 * 1024];
I though I could add a variable at the beginning of each of those functions and dump that variable address and recompile and then look at difference between adjacent functions, but that's lots of manual labor.
How do I quickly identify the function that created a too large set of objects on stack and causes a buffer overflow?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您可以使用 Visual C++ 中的代码分析,该功能在更高版本中可用。如果函数使用的堆栈高于某个限制,则会生成警告 (C6262) 。您可以使用
/analyze:stacksize
开关,其中stacksize
是您想要的限制。You can use Code Analysis in Visual C++ which is available in higher editions. A warning (C6262) is generated if function uses stack higher than some limit. You may use
/analyze:stacksize
switch, wherestacksize
is limit you want.如果您有堆栈跟踪(并且您应该能够获得),您也许能够访问帧的地址。
导致问题的一个函数应该会导致帧指针的巨大飞跃。
如果没有,请检查堆栈大小,它可能太小了。
编辑:如何使用 VC++ 调试不明显的问题? (嗯...我在 Unix 上编码:/)
Elan Rusking 在他的 2011 年 GDC 演示 (PDF)。
堆栈指针(在 x86 上)存储在 ESP 寄存器中。如果您查看反汇编代码并检查 ESP 的更改,那么您应该能够看到哪个函数以较大的值递增/递减了它。
wikibooks 上的示例:
此
add esp
就是您要执行的操作想要追踪。除非您使用 VLA,否则添加/减去的值都是硬编码的,因此很容易检查。If you have a stack trace (and you should be able to get one), you might be able to access the addresses of the frames.
The one function causing the issue should lead to a huge leap in the frames pointers.
If there is none, check the stack size, it might simply be much too small.
EDIT: How to debug non-obvious issues with VC++ ? (hum... I code on Unix :/)
Elan Rusking made a great talk on investigation in his 2011 GDC presentation (PDF).
The stack pointer is (on x86) stored in the
ESP
register. If you have a look at the disassembly and check the changes ofESP
, then you should be able to see which function incremented/decremented it with a large value.Example on wikibooks:
This
add esp
is what you want to track. Unless you are using VLAs, the values added/substracted are hardcoded, so easy to check on.超出其堆栈分配的线程将引发异常。在 Microsoft Visual C++ 中,可以使用
__try
和__except
关键字捕获此异常。您可以将函数包装在该 try- except 块中,以查看它们是否导致堆栈溢出。请查看此处:如何在 Visual C++ 应用程序中捕获堆栈溢出
A thread that exceeds its stack allocation will raise an exception. This exception can be trapped with the
__try
and__except
keywords in Microsoft Visual C++. You can wrap your functions inside this try-except block to see if they cause the stack overflow.Take a look here: How to trap stack overflow in a Visual C++ application