是否有一种便携式/标准的方法可以在堆栈跟踪中获取文件名和亚麻布

Is there a portable/standard-compliant way to get filenames and linenumbers in a stack trace?

本文关键字:堆栈 跟踪 亚麻布 文件名 获取 方法 一种 标准 便携式 是否      更新时间:2023-10-16

我刚刚阅读

当我的GCC C 应用崩溃

时,如何生成堆栈

现在已经很老了(5年)。一些答案表明,解决方案允许您获得每个堆栈框架,功能的名称和偏移量(我猜在堆栈中)。但是,我(和其他人)真正需要的是拨打呼叫的源文件名和行号(假设代码是用调试信息编译的)。链接到GLIBC的一部分的答案之一(libsegfault;请参阅此目录中的文件-segfault.cbacktracesyms.cbacktracesymsfd.c) - 因此它是可能的。。

我的问题是:

  • 可以以独立于平台的方式提取此信息,或者符合某种标准的方式(POSIX ??)
  • 为什么libunwind不支持这一点?(i 思考 在浏览了网站之后)
  • 这是否必须取决于您的编译器的C/C 标准库(至少适用于C/C 应用程序)?

注意:

  • 您可以假设二进制文件具有调试信息,因此,在C/C 的情况下,它是用-g编译的;当然,在适当的库中,我们将检查是否可用。

添加到 @opplyedrussian的有效答案 - 现在有一个多平台库,可以这样做:

Boost StackTrace

,只是为了说明痕迹的外观,如果您要写:

// This following definition may be necessary to ensure you can get
// line numbers included in the stack trace; see:
// https://stackoverflow.com/questions/3899870/
// for details
//
#define BOOST_STACKTRACE_USE_ADDR2LINE
#include <boost/stacktrace.hpp>
// ... somewhere inside the `bar(int)` function that is called recursively:
std::cout << boost::stacktrace::stacktrace();

您可能会得到类似的东西(例如,在Linux上):

0# bar(int) at /path/to/source/file.cpp:70
1# bar(int) at /path/to/source/file.cpp:70
2# bar(int) at /path/to/source/file.cpp:70
3# bar(int) at /path/to/source/file.cpp:70
4# main at /path/to/main.cpp:93
5# __libc_start_main in /lib/x86_64-linux-gnu/libc.so.6
6# _start

可以以独立于平台的方式提取此信息,或者一个符合某种标准的信息(POSIX ??)

除非有人写独立的图书馆来这样做,否则不会。目前没有这样的图书馆(我知道)。

另外,如果通过平台独立,您的意思是"也可以在Windows上使用",请注意,Windows-native调试格式 - PDB,直到最近才有专有性,并且没有记录。

为什么libunwind不支持这一点?(我认为这不是在浏览其网站之后)

libunwind可以支持此如果有人贡献了这样的支持(您是自愿吗?)。但是,这可能会使它的大小四倍,并且目前是有效

这必然取决于您的编译器的C/C 标准库(至少适用于C/C 应用程序)?

否,这仅取决于调试格式。只要记录了该格式(例如Linux上的DWARF4和Windows上的PDB),就可以编写库来解析此类格式,并且没有理由将此类库一定依赖于C++标准库。

P.S。我认为对C标准库的依赖并不是您真正关注的问题。也可能独立于C库,但是必须重新发明轮子 lot ,并且没有实际的理由。

P.P.S。

GDB具有复杂的代码,随着平台而异。

是的,您需要需要该复杂的代码,并且它会随平台而变化。该代码是否属于GDB或libunwind都不会改变。

P.P.P.S。还有lldb,它提供了大部分代码作为库(但我不确定各个平台上的代码如何成熟)。