Трассировка стека отображения C ++ при исключении - PullRequest
172 голосов
/ 28 марта 2009

Я хочу иметь способ сообщить трассировку стека пользователю, если возникнет исключение. Каков наилучший способ сделать это? Требуется ли огромное количество дополнительного кода?

Чтобы ответить на вопросы:

Я бы хотел, чтобы он был портативным, если это возможно. Я хочу, чтобы информация всплывала, чтобы пользователь мог скопировать трассировку стека и отправить ее мне по электронной почте в случае возникновения ошибки.

Ответы [ 14 ]

2 голосов
/ 09 июля 2016

У меня похожая проблема, и хотя мне нравится переносимость, мне нужна только поддержка gcc. В gcc доступны файлы execinfo.h и backtrace . Чтобы разобрать имена функций, у мистера Бингмана есть хороший кусок кода. Чтобы вывести обратную трассировку для исключения, я создаю исключение, которое печатает обратную трассировку в конструкторе. Если бы я ожидал, что это сработает с исключением, сгенерированным в библиотеке, может потребоваться перестройка / компоновка, чтобы использовалось исключение обратного отслеживания.

/******************************************
#Makefile with flags for printing backtrace with function names
# compile with symbols for backtrace
CXXFLAGS=-g
# add symbols to dynamic symbol table for backtrace
LDFLAGS=-rdynamic
turducken: turducken.cc
******************************************/

#include <cstdio>
#include <stdexcept>
#include <execinfo.h>
#include "stacktrace.h" /* https://panthema.net/2008/0901-stacktrace-demangled/ */

// simple exception that prints backtrace when constructed
class btoverflow_error: public std::overflow_error
{
    public:
    btoverflow_error( const std::string& arg ) :
        std::overflow_error( arg )
    {
        print_stacktrace();
    };
};


void chicken(void)
{
    throw btoverflow_error( "too big" );
}

void duck(void)
{
    chicken();
}

void turkey(void)
{
    duck();
}

int main( int argc, char *argv[])
{
    try
    {
        turkey();
    }
    catch( btoverflow_error e)
    {
        printf( "caught exception: %s\n", e.what() );
    }
}

Компиляция и запуск этого с помощью gcc 4.8.4 дает обратную трассировку с хорошо раскрученными именами функций C ++:

stack trace:
 ./turducken : btoverflow_error::btoverflow_error(std::string const&)+0x43
 ./turducken : chicken()+0x48
 ./turducken : duck()+0x9
 ./turducken : turkey()+0x9
 ./turducken : main()+0x15
 /lib/x86_64-linux-gnu/libc.so.6 : __libc_start_main()+0xf5
 ./turducken() [0x401629]
2 голосов
/ 23 октября 2014

Мак может собирать не только трассировку стека, но и значения параметров, локальные переменные и т. Д. - все, что приводит к сбою.

1 голос
/ 11 июня 2015

Следующий код останавливает выполнение сразу после возникновения исключения. Вам необходимо установить обработчик windows_exception_handler и обработчик завершения. Я проверил это в MinGW 32bit.

void beforeCrash(void);

static const bool SET_TERMINATE = std::set_terminate(beforeCrash);

void beforeCrash() {
    __asm("int3");
}

int main(int argc, char *argv[])
{
SetUnhandledExceptionFilter(windows_exception_handler);
...
}

Проверьте следующий код для функции windows_exception_handler: http://www.codedisqus.com/0ziVPgVPUk/exception-handling-and-stacktrace-under-windows-mingwgcc.html

1 голос
/ 16 июня 2013

Cpp-tool ex_diag - легкий, мультиплатформенный, минимальное использование ресурсов, простой и гибкий в трассировке.

...