Can an application programmatically generate its own stacktrace?
我有一个用C编写的程序,运行在Linux、MacOS和Windows上。有没有方法可以调用函数并生成堆栈跟踪?这对我非常有用。理想情况下,我希望在所有三个平台上都这样做,但Linux是最重要的。(Windows正在通过mingw编译。)
谢谢。
型
例如,在gcc和gnu libcc库中,可以使用backtrace()。
正如@slugonamission所建议的,Windows提供CaptureStackBackTrace()-谢谢!
其他平台也可能提供类似的功能。
(这显然是一个依赖平台的问题。)
(在相关注释中,还存在自反汇编库。)
- 对于Windows,此旧日志可能有帮助:日志
- @斯拉格朗纳任务:谢谢你,补充说!
- 这里有一个类似的回溯建议,其中包括引用addr2line程序将偏移量转换为文件名和行号。
型
我正在使用此代码生成调试堆栈跟踪。它使用libunwind获取stacktrace,使用libdwfl读取调试信息。
它产生了漂亮的Java类堆栈跟踪,具有函数名和源位置。如。:
1 2 3 4
| at c(stack_trace.c:95)
at b(stack_trace.c:100)
at a(stack_trace.c:105)
at main(stack_trace.c:110) |
libunwind应该在windows和mac上工作,但是libdwfl是Linux和elf特有的。
- 谢谢。我下载了libunwind,但它没有在我的Mac上编译。
- @你说得对。结果发现它们都是特定于Linux的。
- 当程序崩溃时,我们可以使用libunwind生成回溯吗?
- @Priteshacharya只需在sigsegv信号处理程序中打印stacktrace。不过,要小心这段代码。它充满了未定义的行为。
- 赞成。我不想在sigsegv处理程序中得到新的sigsegv。D
- 我无法安装libdwfl。它不可能是一叶草。我用的是Debian系统。
- 几个小时以来,我一直在寻找一种相对简单的方法来获取文件和行号的堆栈跟踪,这是我找到的第一个也是唯一的答案。谢谢!
- 我同意,这很管用。但是,对于某些函数,如果调用debugInfo(out,(void*)(ip-4)),函数名是错误的,调用debugInfo(out,(void*)(ip))是正确的。我已经证实了这一行为,它也与addr2line一致。我怀疑我遗漏了一些关于程序计数器的基本知识,有人知道为什么会发生这种情况吗?
- @avio unw_reg_ip指向函数将返回的指令。我们需要调用函数的指令。如果没有这个偏移量,您将得到错误的行号。-4是错误的,因为有些调用指令所用的时间比这少。改为试试-1。
- @班瑟谢谢你的建议,但那是我的错。我在构建过程中忘记了删除-O3,所以从某个"深度"开始,我缺少了一些函数调用(可能是内联的),并且从那里开始,在线号码是错误的。我用-O0做了一些试验,并且-4和-1都产生了相同的结果。我仍然缺少一些关于程序计数器的东西,但现在至少它起作用了:)
型
伊恩·兰斯·泰勒的libbacktrace就是这样做的。它处理堆栈展开,并为DWARF调试符号提供支持。
https://github.com/erwanlegrand/libbacktrace
但它只支持小精灵。