C语言 是否有一种可移植的/符合标准的方法来获取堆栈跟踪中的文件名和LinearBers?

ma8fv8wu  于 2023-10-16  发布在  其他
关注(0)|答案(3)|浏览(126)

我刚读了
How to generate a stacktrace when my gcc C++ app crashes
现在已经很老了(5年)。一些答案建议的解决方案允许您为每个堆栈帧获取函数的名称和偏移量(我猜是在堆栈内)。但是我(以及其他人)真正需要的是源文件名和调用所在的行号(假设代码是用调试信息编译的)。其中一个答案与执行此操作的glibc的一部分(libSegfault;参见this directory-segfault.cbacktracesyms.cbacktracesymsfd.c中的文件)-所以这是 * 可能的 *。
我的问题是:

  • 这些信息是否可以以独立于平台的方式提取,或者符合某种标准(POSIX??)
  • 为什么libunwind不支持这个?(我 * 认为 * 它没有,通过therx 1 e2f1x后看)
  • 这是否必须依赖于编译器的C/C标准库(至少对于C/C应用程序)?
    备注:
  • 你可以假设二进制文件有调试信息,所以在C/C++的情况下,它是用-g编译的;当然,在一个适当的库中,我们会检查调试信息是否可用。
dba5bblo

dba5bblo1#

添加到@ EmployeedRussian的有效答案-现在有一个多平台库可以做到这一点:
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
cwxwcias

cwxwcias2#

这些信息是否可以以独立于平台的方式提取,或者符合某种标准(POSIX??)
除非有人写了一个独立于平台的库来这样做。目前还没有这样的图书馆(我知道)。
另外,如果你所说的平台无关是指“也可以在Windows上工作”,那么请注意Windows本机调试格式--PDB,直到最近才被专有和未被文档化。
为什么libunwind不支持这个?(我看了网站后,觉得没有。)
libunwind可以支持这个如果有人贡献这样的支持(你是志愿者吗?然而,这可能会使它的大小增加四倍,而且它目前 * 实际上 * 没有得到维护。
这是否必须依赖于编译器的C/C标准库(至少对于C/C应用程序)?
不,它只取决于调试格式。只要格式被记录下来(例如,Linux上的DWARF4和Windows上的PDB),可以编写一个库来解析这种格式,并且这种库没有必要依赖于C++标准库。
另外,我假设对C标准库的依赖性对您来说不是一个真实的问题。它也可以独立于C库,但是必须重新发明轮子,而且没有实际的理由这样做。
P.P.S.
GDB有复杂的代码,因平台而异。
是的,你需要复杂的代码,而且它会因平台而异。不管代码是在GDB中还是在libunwind中,都不会改变这一点。
P.P.P.S.还有lldb,它以库的形式提供了大部分代码(但我不确定这些代码在各种平台上的成熟程度)。

2skhul33

2skhul333#

有许多堆栈跟踪库可用于收集此信息。
正如einpoklum指出的,有boost stacktrace,但是这个lbirary依赖于外部依赖,并且有可移植性问题。另外请注意,如果没有safe_dump_to,它的堆栈跟踪生成不是ECC信号安全的。
Cpptrace是C++11及更新版本的简单可移植堆栈跟踪库。它目前不支持信号安全跟踪,但它提供了一个原始跟踪接口,可用于以后解析程序计数器的向量。结合最初的帖子How to automatically generate a stacktrace when my program crashes中提到的问题,可以使用backtrace生成堆栈跟踪,然后交给cpptrace解决。
另一个选项是backward-cpp,它提供了一个从信号处理程序跟踪的实用程序。

相关问题