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

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

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

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
Другие вопросы по тегам