2016-11-22 1 views
2

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

How to generate a stacktrace when my gcc C++ app crashes

который довольно старый теперь (5 лет). Некоторые ответы предлагают решения, позволяющие получить для каждого фрейма стека имя функции и смещение (в пределах стека, я думаю). Но мне действительно нужны (и могут другие) исходное имя файла и номер строки, где был сделан вызов (при условии, что код был скомпилирован с информацией об отладке). Один из ответов связан с частью glibc, которая делает это (libSegfault; см. Файлы в this directory - segfault.c, backtracesyms.c, backtracesymsfd.c) - так что это возможно.

Мои вопросы:

  • Может ли эта информация быть извлечена в независимой от платформы моды, или один, что соответствует некоторому стандарту (POSIX ??)
  • Почему не libunwind поддерживает это? (I думаю это не, после просмотра ther website)
  • Это обязательно зависит от стандартной библиотеки вашего компилятора C/C++ (по крайней мере, для приложений на C/C++)?

Примечания:

  • Вы можете предполагать двоичный файл отладочной информации, так и в случае C/C++ он был скомпилирован с -g; конечно, в правильной библиотеке мы будем проверять, доступна ли информация об отладке или нет.
+1

Нет; нет стандартного способа; ни стандарты языка C, ни C++, ни стандарт POSIX o/s не предусматривают способ сделать это. Libunwind, вероятно, настолько близок к тому, чтобы быть столь же портативным, как вы можете получить - может быть несколько других сопоставимых библиотек. И да, это зависит от платформы - o/s и компилятора. Трассировки стека в обработчиках сигналов могут быть ... интересными. –

+0

@JonathanLeffler: Но, скажем, gdb не делает это на многих платформах? Даже для двоичных файлов, не скомпилированных с gcc? – einpoklum

+0

Да, но GDB имеет сложный код, который зависит от платформы, чтобы сделать это. Пойдите и взгляните - это не будет тривиально. Он работает с ABI, определенным для платформы, и зависит от модели отладки (Dwarf vs ...) и формата объектного файла (и исполняемого файла) (ELF vs COFF vs ...) и т. Д. То, что работает на macOS, не будет работать в Windows, и ни одна из них не будет работать в Linux. Вот где вступают в игру библиотеки, такие как libunwind. –

ответ

2

Может ли эта информация быть извлечена в независимой от платформы моды, или один, что соответствует некоторому стандарту (POSIX ??)

Не, если кто-то пишет независимый от платформы библиотеку, чтобы сделать это , На данный момент таких библиотек нет (я знаю).

Кроме того, если независимой платформой вы также подразумеваете «также работает в Windows», то обратите внимание на то, что формат отладки Windows - PDB, был запатентован и недокументирован до недавнего времени.

Почему это не поддерживает libunwind? (Я думаю, что это не так, после просмотра þér сайта)

libunwind может поддержать это если кто способствовал такой поддержки (вы на добровольных началах?). Тем не менее, это, вероятно, в четыре раза увеличит его размер, и в настоящее время он эффективно не поддерживается.

Это обязательно зависит от стандартной библиотеки вашего компилятора C/C++ (по крайней мере, для приложений на C/C++)?

Нет, это зависит только от формата отладки. До тех пор, пока формат документален (например,DWARF4 на Linux и PDB на Windows), можно написать библиотеку для разбора такого формата, и нет никакой причины, чтобы такая библиотека обязательно зависела от стандартной библиотеки C++.

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

P.P.S.

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

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

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

+0

Я бы добровольно, если бы у меня было больше свободного времени на моих руках. Я выпустил некоторые FOSS раньше ... но, увы, это не способствует моим исследованиям, поэтому я не могу сделать это на «рабочем времени». Однако PPPS должен стать многообещающим. – einpoklum

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 
Смежные вопросы