我参加了一些介绍堆栈使用的在线课程,它们很好但很理论。因此,我一直试图通过展示一些简单的C程序的堆栈来理解它。我找到了几种方法,并尝试使用gdb(backtrace ...)。
但是,我只能在发生错误时显示堆栈信息。我想知道是否有一种方法只显示堆栈即使程序正确运行?
答案 0 :(得分:3)
理论上,你不能确定是否有任何堆栈。
例如,编译器可以inline进行每个函数调用。或者它可以做一些整个程序static analysis并发现不需要堆栈。或者编译器对optimize进行了tail calls次调用。
更现实地说,某些函数中的局部变量都可以进入寄存器(优化时)。
实际上,您可以在调试器(例如gdb
)和停止程序中运行程序(例如,在{{1中使用 Ctrl C ) }} session,然后运行调试过程的gdb
和examine the stack的backtrace
(或bt
)命令。
(以下信息是高级的;如果您是新手,请不要混淆;并且在编译时,从程序内部或调试器中可以做到的事情时要非常小心)
如果要在Linux(使用GNU libc)的程序中以编程方式访问<{3}} ,可以使用call stack(它们不是标准的,也可能不是工作,尤其是强有力的优化)。甚至backtrace functions(然后使用gdb
更好地编译所有代码,因为-g
使用Ian Taylor libbacktrace格式的调试信息。)
在评论中你添加了:
我正在寻找一种在堆栈中显示详细信息的方法,例如参数,变量,SP等的值。
这通常是不可能的(在运行时,从程序内部)。变量和参数仅为编译器所知(并且在运行时会被遗忘)。在机器代码中,您只有内存位置和寄存器(以及可能堆栈帧,这可能会因DWARF ....而丢失)。此外,您经常会使用某些-fomit-stack-pointer
compile option编译C代码,然后很可能某些变量不在堆栈中(但仅限于寄存器中)。
请注意,C没有optimizations或introspection,没有明确reflection,也不是continuations语言。
答案 1 :(得分:2)
我想知道即使程序运行正确,是否有办法显示堆栈?
是的:您可以在程序执行的任意点检查堆栈:只需在感兴趣的指令上设置断点,或者单步执行整个程序。
例如:
(gdb) break main
(gdb) run
... program stops after main prolog
(gdb) where # examine stack
(gdb) stepi # execute one instruction
(gdb) where
(gdb) stepi
... repeat until you reach syscall SYS_exit, or until you are too bored to continue