2010-11-26 13 views
15

Estoy usando backtrace para obtener la información de dónde se emite la excepción. En el constructor de mi excepción, estoy almacenando el backtrace en std :: string, y en el bloque catch para excepciones de este tipo, estoy imprimiendo este backtrace.Obteniendo la traza inversa del bloque catch

Pero me preguntaba, ¿es posible de alguna manera obtener la misma traza inversa en el bloque catch para otros tipos de excepciones?

+0

Es posible que desee echar un vistazo a [esta publicación] (http://stackoverflow.com/questions/3355683/c-stack-trace-from-unhandled-exception "c-stack-trace-from-unhandled- excepción"). Puede llevarte a algún lugar cerca de donde quieras estar. –

+0

El problema con std :: set_terminate es que el programa aún terminará cuando se llame a la devolución de llamada. –

Respuesta

8

No lo creo. Cuando los ejecutores se detienen en el bloque catch, la pila se desenrolla, y todo lo que sucedió antes ya no está en la pila.

+0

Sí, exactamente. Lo que nos lleva a "¿cómo hago algo cuando la excepción es * arrojado *"? - http://stackoverflow.com/q/4223390/57428 – sharptooth

+0

Len Holgate mencionó Debug API para atrapar la excepción exactamente cuando se lanza. Parece complicado, pero factible. – Dialecticus

9

Puede que esté interesado en una biblioteca de Boost en desarrollo: Portable Backtrace. Ejemplo:

#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); 
    } 
} 

Lienzo:

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 

Espero que esto ayude!

+0

Sí, eso es exactamente lo que necesito, pero hasta donde puedo ver, todavía está en la versión de refuerzo, y en este momento estoy bloqueado en impulsar 1.34.1 :( –

+2

Tal vez pueda descargarlo por separado y usarlo Independiente. Luego, cuando/si se convierte en un Boost oficial, es posible que puedas cambiar/actualizar. ¡Buena suerte! –

+1

Disculpa, pero me di cuenta de que esto no responde mi pregunta. Para esto, tienes que lanzar excepciones de impulso, pero la traza inversa no se imprime si se detecta otro tipo de excepción. –

1

¿Las clases en cuestión comparten una base común que usted puede editar?

De lo contrario, proporcioné una respuesta maravillosa pero terriblemente subestimada al How can some code be run each time an exception is thrown in a Visual C++ program? ;-P Algunos otros opinaron también.

+0

Pero no soy linux, por lo tanto no hay estudio visual aquí;) –

+0

Sí, las clases de excepción que estoy lanzando tener una base común, y puedo obtener la traza inversa para aquellos. El problema es cómo obtener el seguimiento de otros tipos de excepción? Por ejemplo, std :: out_of_range –

+0

@VJo: mi hack sucio no era específico de Visual C++ (de hecho, lo probé solo en GCC), pero tampoco es adecuado para un uso serio de producción. Para std :: out_of_range, es una molestia, supongo que depende de lo valioso que sea para ti, pero podrías explorar el cambio de std :: exception en sí mismo, usando técnicas de depuración. ¿Está tratando con std :: out_of_range y otros lanzados desde bibliotecas de terceros (si es así, incluso tiene fuentes), o simplemente en su propio código? ¿Hay demasiada fuente para cambiar las declaraciones de tiro? –

Cuestiones relacionadas