C运行时stackoverflow
#include <stdio.h> int doHello(){ doHello(); } int main(){ doHello(); printf("nLeaving Main"); return 0; } 当您运行此程序时,程序退出而不在屏幕上打印“Leaving Main”消息.这是Stack Overflow的情况,因为程序正在终止,但我在命令窗口中看不到任何错误消息. (跑在Windows / Cygwin /) Q1.我没有在doHello函数中声明任何局部变量,但仍在使用堆栈.这是因为 >返回值 澄清 Q2.如何在程序中调试此类案例?我不是要求调试我上面提到的无限循环. 例如: #define SIZE 512*1024 void doOVerflow(){ char str[SIZE]; doHello(); } void doHello(){ char strHello[256]; // stack gets filled up at this point doNothing(); // program terminates and function doNothing does not get called } 编辑: Q3.运行时堆栈中存储了哪些信息? 解决方法
通常是帧指针和返回地址.参见例如
wikipedia’s “call stack” article.万一你好奇:
$gcc -S test.c # <--- assembles,but does not compile,test.c; output in test.s $cat test.s // [some contents snipped] _doHello: pushl %ebp // <--- pushes address of stack frame onto stack movl %esp,%ebp // <--- sets up new stack frame call _doHello // <--- pushes return value onto stack,makes call popl %ebp // <--- pops address of stack frame off stack ret // <--- pops return value off stack,returns to it 为了好玩,试试“-fomit-frame-pointers”: $gcc -fomit-frame-pointers -S test.c $cat test.s // [some contents snipped] _doHello: call _doHello // <--- pushes return value onto stack,makes call ret // <--- pops return value off stack,returns to it 为了获得更多乐趣,让我们看看当我们开启优化时会发生什么: $gcc -fomit-frame-pointers -O4 -S test.c # <--- heavy optimization $cat test.s // [some contents snipped] _doHello: L2: jmp L2 // <--- no more stack operations! 最后一个版本将永远运行,而不是退出,至少在我的设置上(cygwin,目前). 要诊断这样的问题,您可以在您喜欢的调试器(例如Microsoft Visual C或gdb)中运行,或者使用这些调试器检查通常由大多数系统(.core或.stackdump文件)生成的stackdumps. 如果您的调试器支持这一点,您也可以在堆栈顶部附近设置硬件断点 – 任何尝试写入此变量,并且您的堆栈可能已满.某些操作系统具有其他机制来提醒您堆栈溢出. 最后,调试环境(如valgrind或Application Verifier)可能会有所帮助. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |