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

僤鯓⒐⒋嵵緔 提交于 2019-12-01 21:13:01

Can this information be extracted in a platform-independent fashion, or one that conforms to some standard (POSIX??)

Not unless someone writes a platform-independent library to do so. There are no such libraries (that I am aware of) at the moment.

Also, if by platform independent you mean "also works on Windows", then note that the Windows-native debugging format -- the PDB, was proprietary and undocumented until very recently.

Why doesn't libunwind support this? (I think it doesn't, after looking through ther website)

libunwind could support this if someone contributed such support (are you volunteering?). However, that would probably quadruple its size, and it currently is effectively unmaintained.

Does this necessarily depend on your compiler's C/C++ standard library (for C/C++ apps, at least)?

No, it only depends on the debug format. So long as the format is documented (e.g. DWARF4 on Linux and PDB on Windows), it's possible to write a library to parse such format, and there is no reason for such library to necessarily depend on C++ standard library.

P.S. I assume that dependence on the C standard library isn't a real concern for you. It's also possible to be independent of the C library, but one would have to reinvent the wheel a lot, and there is no practical reason to do so.

P.P.S.

GDB has complex code that varies by platform to do it.

Yes, and you need that complex code, and it will vary by platform. Whether that code lives in GDB or in libunwind doesn't change that.

P.P.P.S. There is also lldb, which provides much of that code as a library (but I am not sure how mature that code on various platforms is).

Adding to @EmployedRussian's valid answer - there is now a multi-platform library which does this:

Boost StackTrace

And just to illustrate what a trace looks like, if you were to write:

// 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();

you might get something like (on Linux for example):

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
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!