Estoy trabajando en una aplicación multiproceso y quiero depurarla usando GDB.
El problema es que uno de mis hilos sigue muriendo con el mensaje:
pure virtual method called
terminate called without an active exception
Abort
Conozco la causa de ese mensaje, pero no tengo idea de en qué parte de mi hilo ocurre. Realmente sería útil un seguimiento.
Cuando ejecuto mi aplicación en GDB, se detiene cada vez que se suspende o reanuda un hilo. Quiero que mi aplicación continúe ejecutándose normalmente hasta que uno de los subprocesos muera con esa excepción, momento en el que todo debería detenerse para poder obtener un seguimiento.
handle SIGUSR1 pass noprint nostop
Respuestas:
Puede intentar usar un "punto de captura" (
catch throw
) para detener el depurador en el punto donde se genera la excepción.El siguiente extracto del manual de gdb describe la función de punto de captura.
5.1.3 Establecer puntos de captura
Puede usar puntos de captura para hacer que el depurador se detenga para ciertos tipos de eventos de programa, como excepciones de C ++ o la carga de una biblioteca compartida. Utilice el comando catch para establecer un punto de captura.
evento de captura
lanzar
captura
ejecutivo
tenedor
vfork
cargar o cargar libname
descargar o descargar libname
evento tcatch
Utilice el
info break
comando para enumerar los puntos de captura actuales.Actualmente existen algunas limitaciones para el manejo de excepciones de C ++ (catch throw y catch catch) en GDB:
Si llama a una función de forma interactiva, GDB normalmente le devuelve el control cuando la función ha terminado de ejecutarse. Sin embargo, si la llamada genera una excepción, la llamada puede omitir el mecanismo que le devuelve el control y hacer que su programa se anule o simplemente continúe ejecutándose hasta que llegue a un punto de interrupción, capte una señal de que GDB está escuchando o salga. Este es el caso incluso si establece un punto de captura para la excepción; los puntos de captura en las excepciones están deshabilitados dentro de las llamadas interactivas.
No puede plantear una excepción de forma interactiva.
No puede instalar un controlador de excepciones de forma interactiva.
A veces, catch no es la mejor manera de depurar el manejo de excepciones: si necesita saber exactamente dónde se genera una excepción, es mejor detenerse antes de que se llame al controlador de excepciones, ya que de esa manera puede ver la pila antes de que se realice cualquier desenrollado. Si establece un punto de interrupción en un controlador de excepciones, puede que no sea fácil averiguar dónde se generó la excepción.
Para detenerse justo antes de que se llame a un controlador de excepciones, necesita algunos conocimientos de la implementación. En el caso de GNU C ++, las excepciones se generan al llamar a una función de biblioteca llamada __raise_exception que tiene la siguiente interfaz ANSI C:
Para que el depurador detecte todas las excepciones antes de que se produzca el desenrollado de la pila, establezca un punto de interrupción en __raise_exception (consulte la sección Puntos de interrupción, puntos de observación y excepciones).
Con un punto de interrupción condicional (consulte la sección Condiciones de interrupción) que depende del valor de id, puede detener su programa cuando se genera una excepción específica. Puede utilizar varios puntos de interrupción condicionales para detener su programa cuando se genera alguna de las excepciones.
fuente
catch throw std::runtime_exception
.Establecer un punto de interrupción en __pure_virtual
fuente
FWIW, aparentemente, en gcc 4.1, el nombre de función apropiado ha cambiado y uno debe establecer un punto de interrupción en esta función.
__cxa_pure_virtual
fuente
Solo debajo de uno funcionó para mí con gdb 8.3:
"atrapar tiro" o "romper __cxx_throw" no funcionó para mí.
fuente