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