Существует ли портативный / совместимый со стандартами способ получения имен файлов и номеров белья в трассировке стека?

Я только что прочитал

Как создать трассировку стека при сбое моего приложения 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++ стандартная библиотека.

Постскриптум Я предполагаю, что зависимость от C стандартная библиотека вас не беспокоит. Также возможно быть независимым от C библиотека, но придется изобретать велосипед много, и нет никаких практических причин для этого.

P.P.S.

GDB имеет сложный код, который зависит от платформы, чтобы сделать это.

Да и ты необходимость этот сложный код, и это будут варьироваться в зависимости от платформы. Живет ли этот код в GDB или в libunwind не меняет это.

P.P.P.S. Существует также lldb, который предоставляет большую часть этого кода в виде библиотеки (но я не уверен, насколько зрелым этот код на различных платформах).

2

Другие решения

Добавление к правильному ответу @ EmployedRussian — нет многоплатформенной библиотеки, которая делает это:

Boost StackTrace

И просто чтобы проиллюстрировать, как выглядит трассировка, если бы вы написали:

#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
2

По вопросам рекламы [email protected]