2010-11-26 2 views
15

Я использую backtrace, чтобы получить информацию, откуда выбрасывается исключение. В конструкторе моего исключения я сохраняю обратную трассировку в std :: string, а в блоке catch для исключений этого типа я печатаю эту обратную трассировку.Получение backtrace из блока catch

Но мне было интересно, возможно ли каким-то образом получить такую ​​же обратную трассировку в блоке catch для других типов исключений?

+0

Возможно, вы захотите просмотреть [этот пост] (http://stackoverflow.com/questions/3355683/c-stack-trace-from-unhandled-exception "c-stack-trace-from-unhandled- исключение "). Это может привести вас где-нибудь рядом с тем, где вы хотите быть. – 2010-11-26 09:29:32

+0

Проблема с std :: set_terminate заключается в том, что программа будет прекращаться при вызове обратного вызова. – 2010-11-26 13:58:38

ответ

8

Я так не считаю. Когда исполнители останавливаются в блоке catch, стек разматывается, и все, что произошло раньше, больше не находится в стеке.

+0

Да, точно. Это приводит нас к «как мне что-то делать, когда исключение * выбрано» - http://stackoverflow.com/q/4223390/57428 – sharptooth 2010-11-26 10:53:19

+0

Лен Холгейт упомянул API отладки, чтобы перехватывать исключение именно тогда, когда его бросают. Кажется сложным, но выполнимым. – Dialecticus 2010-11-26 10:57:04

9

Возможно, вас заинтересует библиотека Boost: Portable Backtrace. Пример:

#include <boost/backtrace.hpp> 
#include <iostream> 

int foo() 
{ 
    throw boost::runtime_error("My Error"); 
    return 10; 
} 

int bar() 
{ 
    return foo()+20; 
} 


int main() 
{ 
    try { 
     std::cout << bar() << std::endl; 
    } 
    catch(std::exception const &e) 
    { 
     std::cerr << e.what() << std::endl; 
     std::cerr << boost::trace(e); 
    } 
} 

Печать:

My Error 
0x403fe1: boost::stack_trace::trace(void**, int) + 0x1b in ./test_backtrace 
0x405451: boost::backtrace::backtrace(unsigned long) + 0x65 in ./test_backtrace 
0x4054d2: boost::runtime_error::runtime_error(std::string const&) + 0x32 in ./test_backtrace 
0x40417e: foo() + 0x44 in ./test_backtrace 
0x40425c: bar() + 0x9 in ./test_backtrace 
0x404271: main + 0x10 in ./test_backtrace 
0x7fd612ecd1a6: __libc_start_main + 0xe6 in /lib/libc.so.6 
0x403b39: __gxx_personality_v0 + 0x99 in ./test_backtrace 

Надеется, что это помогает!

1

Имеют ли классы, о которых идет речь, общую базу, которую вы можете редактировать?

В противном случае я предоставил замечательный, но ужасно недооцененный ответ на How can some code be run each time an exception is thrown in a Visual C++ program? ;-P Некоторые другие высказали мнение.