c++ - cassert - function assert
¿Cuál es la forma correcta de romper las afirmaciones fallidas en gdb? (3)
Establecer un punto de interrupción en abort()
parece ser la mejor respuesta.
break abort
en la CLI de gdb.
Estoy intentando capturar afirmaciones fallidas en mi programa. Estoy usando una biblioteca que hace llamadas directas a assert (), en lugar de una función o macro personalizada, y actualmente, dentro de esta biblioteca, estoy tratando de rastrear varios errores relacionados con los puertos. Todo lo involucrado ha sido compilado con símbolos de depuración en g ++.
La mejor solución que he encontrado es romper en el archivo: línea de la afirmación, con la condición de la expresión de afirmación. Esto permite detener la afirmación antes de que falle, pero es una solución horrible. Requiere una configuración especial para cada aserción que pueda fallar, no funcionará desde mi IDE y es demasiado esfuerzo en general.
¿Cómo puedo interrumpir cualquier asalto fallido utilizando gdb & gcc de tal manera que permita el examen de la pila de llamadas y las variables dentro del alcance de la llamada asertiva?
Sería aún mejor si la solución me permitiera descartar el fallo de la afirmación y continuar ejecutándose.
Si las respuestas sugeridas anteriormente no funcionan para usted, puede intentar interrumpir la función __assert_fail.
break __assert_fail
Es muy probable que el nombre dependa de la implementación, pero es fácil de encontrar si nos fijamos en la definición de macro de afirmación en su plataforma. Esto te permitirá romper antes de SIGABRT.
No se necesita ninguna break
en Linux, simplemente escriba bt
en el indicador
abort()
hace que se genere una señal en Linux, y GDB ya interrumpe las señales de forma predeterminada.
P.ej:
#include <assert.h>
void g(int i) {
assert(0);
}
void f(int i) {
g(i);
}
int main(void) {
f(1);
}
Entonces:
gcc -std=c99 -O0 -ggdb3 -o a a.c
gdb -ex run ./a
Luego simplemente escribe bt
en el shell:
(gdb) bt
#0 __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:58
#1 0x00007ffff7a483ea in __GI_abort () at abort.c:89
#2 0x00007ffff7a3ebb7 in __assert_fail_base (fmt=<optimized out>, assertion=assertion@entry=0x555555554788 "0", file=file@entry=0x555555554784 "a.c", line=line@entry=4,
function=function@entry=0x55555555478a <__PRETTY_FUNCTION__.1772> "g") at assert.c:92
#3 0x00007ffff7a3ec62 in __GI___assert_fail (assertion=0x555555554788 "0", file=0x555555554784 "a.c", line=4, function=0x55555555478a <__PRETTY_FUNCTION__.1772> "g")
at assert.c:101
#4 0x00005555555546ca in g (i=1) at a.c:4
#5 0x00005555555546df in f (i=1) at a.c:8
#6 0x00005555555546f0 in main () at a.c:12
Lo que ya muestra los valores de la función ( f (i=1)
).
Y también puedes hacer como de costumbre:
(gdb) f 4
#4 0x00005555555546ca in g (i=1) at a.c:4
4 assert(0);
(gdb) p i
$1 = 1
Probado en Ubuntu 16.10, gdb 7.11.