Я только что прочитал
Как создать трассировку стека при сбое моего приложения gcc C ++
который довольно старый (5 лет). В некоторых ответах предлагаются решения, позволяющие получить для каждого фрейма стека имя функции и смещение (я думаю, внутри стека). Но что мне (и, возможно, другим) действительно нужно, это имя файла источника и номер строки, где был сделан вызов (при условии, что код был скомпилирован с отладочной информацией). Один из ответов связан с частью glibc, которая делает это (libSegfault; см. Файлы в этот каталог — segfault.c
, backtracesyms.c
, backtracesymsfd.c
) — так что, это возможный.
Мои вопросы:
Заметки:
-g
; конечно, в правильной библиотеке мы будем проверять, доступна ли отладочная информация или нет.Может ли эта информация извлекаться независимо от платформы или в соответствии с каким-либо стандартом (POSIX ??)
Нет, если кто-то не напишет независимую от платформы библиотеку для этого. На данный момент нет таких библиотек (о которых я знаю).
Кроме того, если под независимостью от платформы вы подразумеваете «также работает в Windows», то обратите внимание, что собственный формат отладки Windows — PDB
, был собственностью и без документов до совсем недавно.
Почему libunwind не поддерживает это? (Я думаю, что нет, после просмотра веб-сайта)
libunwind
может поддержать это если кто-то внес такую поддержку (вы добровольно?). Тем не менее, это, вероятно, в четыре раза больше, и в настоящее время фактически никто не поддерживался.
Обязательно ли это зависит от стандартной библиотеки вашего компилятора C / C ++ (по крайней мере, для приложений C / C ++)?
Нет, это зависит только от формата отладки. До тех пор, пока формат задокументирован (например, DWARF4
в Linux и PDB
в Windows), можно написать библиотеку для разбора такого формата, и нет никаких причин для такой библиотеки обязательно зависеть от C++
стандартная библиотека.
Постскриптум Я предполагаю, что зависимость от C
стандартная библиотека вас не беспокоит. Также возможно быть независимым от C
библиотека, но придется изобретать велосипед много, и нет никаких практических причин для этого.
P.P.S.
GDB имеет сложный код, который зависит от платформы, чтобы сделать это.
Да и ты необходимость этот сложный код, и это будут варьироваться в зависимости от платформы. Живет ли этот код в GDB или в libunwind
не меняет это.
P.P.P.S. Существует также lldb
, который предоставляет большую часть этого кода в виде библиотеки (но я не уверен, насколько зрелым этот код на различных платформах).
Добавление к правильному ответу @ EmployedRussian — нет многоплатформенной библиотеки, которая делает это:
И просто чтобы проиллюстрировать, как выглядит трассировка, если бы вы написали:
#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