Quiero tener una manera de informar el seguimiento de la pila al usuario si se produce una excepción. ¿Cuál es la mejor manera de hacer esto? ¿Se necesita una gran cantidad de código extra?
Para responder preguntas:
Me gustaría que sea portátil si es posible. Quiero que aparezca información emergente, para que el usuario pueda copiar el seguimiento de la pila y enviarme un correo electrónico si aparece un error.
Linux
nogcc
.libstdc++
(utilizado por GCC y potencialmente Clang) como se explica en esta respuesta .La respuesta de Andrew Grant no ayuda a obtener un seguimiento de la pila de la función de lanzamiento , al menos no con GCC, porque una instrucción throw no guarda el seguimiento de la pila actual por sí solo, y el controlador catch no tendrá acceso al seguimiento de la pila en ese punto más.
La única forma, usando GCC, de resolver esto es asegurándose de generar un seguimiento de la pila en el punto de la instrucción de lanzamiento, y guardarlo con el objeto de excepción.
Este método requiere, por supuesto, que cada código que arroje una excepción use esa clase de excepción en particular.
Actualización 11 de julio de 2017 : para obtener un código útil, eche un vistazo a la respuesta de cahit beyaz, que apunta a http://stacktrace.sourceforge.net . Todavía no lo he usado, pero parece prometedor.
fuente
throw stack_runtime_error
. ¿Estoy en lo cierto al deducir que esta biblioteca solo funciona para excepciones derivadas de esa clase, y no parastd::exception
excepciones de bibliotecas de terceros?Si está utilizando Boost 1.65 o superior, puede usar boost :: stacktrace :
fuente
Unix: retroceso
Mac: retroceder
Windows: CaptureBackTrace
fuente
Me gustaría agregar una opción de biblioteca estándar (es decir, multiplataforma) sobre cómo generar rastreos de excepción, que está disponible con C ++ 11 :
Uso
std::nested_exception
ystd::throw_with_nested
Esto no te dará un montón de descanso, pero en mi opinión lo mejor. Se describe en StackOverflow aquí y aquí , cómo puede obtener un seguimiento de sus excepciones dentro de su código sin necesidad de un depurador o un registro engorroso, simplemente escribiendo un controlador de excepciones adecuado que arroje excepciones anidadas.
Como puede hacer esto con cualquier clase de excepción derivada, ¡puede agregar mucha información a dicha traza inversa! También puede echar un vistazo a mi MWE en GitHub , donde una traza inversa se vería así:
fuente
AFAIK libunwind es bastante portátil y hasta ahora no he encontrado nada más fácil de usar.
fuente
Recomiendo http://stacktrace.sourceforge.net/ project. Es compatible con Windows, Mac OS y también Linux
fuente
throw stack_runtime_error
. ¿Estoy en lo cierto al deducir que esta biblioteca solo funciona para excepciones derivadas de esa clase, y no parastd::exception
excepciones de bibliotecas de terceros?Si está utilizando C ++ y no quiere / no puede usar Boost, puede imprimir la traza inversa con los nombres solicitados utilizando el siguiente código [enlace al sitio original] .
Tenga en cuenta que esta solución es específica de Linux. Utiliza las funciones libc de GNU backtrace () / backtrace_symbols () (de execinfo.h) para obtener los retrocesos y luego usa __cxa_demangle () (de cxxabi.h) para solicitar los nombres de los símbolos de retroceso.
HTH!
fuente
en Linux con g ++ echa un vistazo a esta lib
https://sourceforge.net/projects/libcsdbg
Hace todo el trabajo por ti
fuente
En Windows, echa un vistazo a BugTrap . Ya no está en el enlace original, pero todavía está disponible en CodeProject.
fuente
Tengo un problema similar, y aunque me gusta la portabilidad, solo necesito soporte de gcc. En gcc, execinfo.h y los backtrace llamadas están disponibles. Para exigir los nombres de las funciones, el Sr. Bingmann tiene un buen código. Para volcar un rastreo en una excepción, creo una excepción que imprime el rastreo en el constructor. Si esperaba que esto funcionara con una excepción lanzada en una biblioteca, podría requerir la reconstrucción / vinculación para que se use la excepción de rastreo.
Compilar y ejecutar esto con gcc 4.8.4 produce una traza inversa con nombres de funciones de C ++ muy bien desarmados:
fuente
Como la pila ya está desenrollada al ingresar al bloque catch, la solución en mi caso fue no capturar ciertas excepciones que luego conducen a un SIGABRT. En el controlador de señal para SIGABRT, luego bifurco () y execl () gdb (en compilaciones de depuración) o stackpacks de Google breakpads (en compilaciones de lanzamiento). También trato de usar solo las funciones seguras del controlador de señal.
GDB:
minidump_stackwalk:
Editar: para que funcione para el breakpad también tuve que agregar esto:
Fuente: ¿Cómo obtener un seguimiento de pila para C ++ usando gcc con información de número de línea? y ¿Es posible adjuntar gdb a un proceso bloqueado (también conocido como depuración "justo a tiempo")
fuente
Poppy puede recopilar no solo el seguimiento de la pila, sino también los valores de los parámetros, las variables locales, etc., todo lo que conduce al bloqueo.
fuente
El siguiente código detiene la ejecución justo después de que se lanza una excepción. Debe establecer un controlador_excepción_ windows junto con un controlador de terminación. Probé esto en MinGW 32bits.
Verifique el siguiente código para la función windows_exception_handler: http://www.codedisqus.com/0ziVPgVPUk/exception-handling-and-stacktrace-under-windows-mingwgcc.html
fuente
Cpp-tool ex_diag : peso fácil, multiplataforma, uso mínimo de recursos, simple y flexible en el rastreo.
fuente