c++ - Ejecutar una aplicación en GDB hasta que ocurra una excepción
debugging polymorphism (3)
Establecer un punto de interrupción en __pure_virtual
Estoy trabajando en una aplicación multiproceso, y quiero depurarlo 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
Sé la causa de ese mensaje, pero no tengo idea de dónde se produce en mi hilo. Un backtrace realmente sería útil.
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 hilos fallezca con esa excepción, momento en el que todo debería detenerse para poder obtener una traza inversa.
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
Puede intentar usar un "punto de captura" ( catch throw
) para detener el depurador en el punto donde se genera la excepción.
El siguiente excerpt del manual de gdb describe la función de punto de referencia.
5.1.3 Establecer puntos de captura
Puede usar puntos de conexión 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. Use el comando catch para establecer un punto de referencia.
evento de captura
Detener cuando ocurre un evento . evento puede ser cualquiera de los siguientes:
lanzar
El lanzamiento de una excepción C ++.
captura
La captura de una excepción de C ++.
ejecutivo
Una llamada al ejecutivo Actualmente, esto solo está disponible para HP-UX.
tenedor
Una llamada a la bifurcación. Actualmente, esto solo está disponible para HP-UX.
vfork
Una llamada a vfork. Actualmente, esto solo está disponible para HP-UX.
cargar o cargar nombre de lib
La carga dinámica de cualquier biblioteca compartida, o la carga de la biblioteca libname. Actualmente, esto solo está disponible para HP-UX.
descargar o descargar nombre de lib
La descarga de cualquier biblioteca compartida cargada dinámicamente, o la descarga de la librería libname. Actualmente, esto solo está disponible para HP-UX.
evento de captura
Establezca un punto de captura que está habilitado solo para una parada. El punto de captura se elimina automáticamente después de la primera captura del evento.
Utilice el comando de info break
para enumerar los puntos de captura actuales.
Actualmente hay algunas limitaciones para el manejo de excepciones C ++ (catch catch y catch catch) en GDB:
* If you call a function interactively, GDB normally returns control to you when the function has finished executing. If the call raises an exception, however, the call may bypass the mechanism that returns control to you and cause your program either to abort or to simply continue running until it hits a breakpoint, catches a signal that GDB is listening for, or exits. This is the case even if you set a catchpoint for the exception; catchpoints on exceptions are disabled within interactive calls.
* You cannot raise an exception interactively.
* You cannot install an exception handler interactively.
A veces la captura no es la mejor manera de depurar el manejo de excepciones: si necesita saber exactamente dónde se produce una excepción, es mejor detenerse antes de que se llame al manejador de excepciones, ya que de esa manera puede ver la pila antes de que se produzca algún desenrollado. Si establece un punto de interrupción en un manejador de excepciones en su lugar, puede no ser fácil averiguar dónde se produjo la excepción.
Para detenerse justo antes de que se llame a un manejador de excepciones, necesita algún conocimiento de la implementación. En el caso de GNU C ++, las excepciones se producen llamando a una función de biblioteca llamada __raise_exception que tiene la siguiente interfaz ANSI C:
/* addr is where the exception identifier is stored.
id is the exception identifier. */
void __raise_exception (void **addr, void *id);
Para que el depurador capte todas las excepciones antes de que se desenrolle 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 la identificación, puede detener su programa cuando se produce una excepción específica. Puede usar múltiples puntos de interrupción condicionales para detener su programa cuando se produce una de una serie de excepciones.