如何在C中显示堆栈的内容?

时间:2017-02-18 08:38:48

标签: c linux operating-system gdb stack

我参加了一些介绍堆栈使用的在线课程,它们很好但很理论。因此,我一直试图通过展示一些简单的C程序的堆栈来理解它。我找到了几种方法,并尝试使用gdb(backtrace ...)。

但是,我只能在发生错误时显示堆栈信息。我想知道是否有一种方法只显示堆栈即使程序正确运行?

2 个答案:

答案 0 :(得分:3)

理论上,你不能确定是否有任何堆栈。

例如,编译器可以inline进行每个函数调用。或者它可以做一些整个程序static analysis并发现不需要堆栈。或者编译器对optimize进行了tail calls次调用。

更现实地说,某些函数中的局部变量都可以进入寄存器(优化时)。

实际上,您可以在调试器(例如gdb)和停止程序中运行程序(例如,在{{1中使用 Ctrl C ) }} session,然后运行调试过程的gdbexamine the stackbacktrace(或bt)命令。

(以下信息是高级的;如果您是新手,请不要混淆;并且在编译时,从程序内部或调试器中可以做到的事情时要非常小心)

如果要在Linux(使用GNU libc)的程序中以编程方式访问<{3}} ,可以使用call stack(它们不是标准的,也可能不是工作,尤其是强有力的优化)。甚至backtrace functions(然后使用gdb更好地编译所有代码,因为-g使用Ian Taylor libbacktrace格式的调试信息。)

在评论中你添加了:

  

我正在寻找一种在堆栈中显示详细信息的方法,例如参数,变量,SP等的值。

这通常是不可能的(在运行时,从程序内部)。变量和参数仅为编译器所知(并且在运行时会被遗忘)。在机器代码中,您只有内存位置和寄存器(以及可能堆栈帧,这可能会因DWARF ....而丢失)。此外,您经常会使用某些-fomit-stack-pointer compile option编译C代码,然后很可能某些变量不在堆栈中(但仅限于寄存器中)。

请注意,C没有optimizationsintrospection,没有明确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