【问题标题】:How can I show the content of stack in C?如何在 C 中显示堆栈的内容?
【发布时间】:2023-04-06 11:45:01
【问题描述】:

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

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

【问题讨论】:

  • 我们说的是“调用栈”而不是“数据栈”,对吧?
  • 是的,Aubin,确实是调用堆栈。感谢您提供的信息,我刚刚尝试过。但回溯似乎只显示被调用的函数。我正在寻找一种在堆栈中显示详细信息的方法,例如参数值、变量、SP 等。
  • @Rick:请编辑您的问题而不是评论它......

标签: c linux operating-system gdb stack


【解决方案1】:

理论上,您无法确定是否存在任何堆栈。

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

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

实际上,您可以在调试器中运行您的程序(如gdb)并停止该程序(例如在您的gdb 会话中使用Ctrl C) ,然后运行被调试进程的gdbexamine the stackbacktrace(或bt)命令。


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

如果您想在 Linux(使用 GNU libc)的程序中访问call stack 以编程方式,您可以使用backtrace functions(它们不是标准的,可能无法正常工作,尤其是具有强大的优化)。甚至是Ian Taylor libbacktrace(然后最好用-g编译所有代码,因为libbacktrace使用DWARF格式的调试信息)。

在您添加的评论中:

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

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

请注意,C 没有introspection,或reflection,没有显式continuations,也不是homoiconic 语言。

【讨论】:

  • 这解决了我遇到的问题并给出了很好的解释。非常感谢
【解决方案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

【讨论】:

  • @BasileStarynkevitch 他在询问如何使用调试器检查状态(只是不在崩溃点)。请注意问题上的 GDB 标记。
猜你喜欢
  • 2015-03-03
  • 2020-12-18
  • 1970-01-01
  • 1970-01-01
  • 2021-02-06
  • 2012-02-25
  • 1970-01-01
  • 2020-03-24
  • 1970-01-01
相关资源
最近更新 更多