usar tutorial subaru onlinegdb online español como commands c gdb

tutorial - ¿Qué podría hacer que GDB se niegue a romper?



online gdb python (4)

Estoy perdido aquí. Estoy escribiendo un compilador en C (para hobby) y compilando con GCC 4.6.1 en amd64 Linux 2.6.32, usando GDB 7.3. Las banderas son "-Wall -Wextra -O0 -g", además del habitual -I y lo que sea. Tengo una función cuyo propósito es informar un error de análisis, definido de la siguiente manera:

void cerror_at (struct lex *lex, struct token *tok, const char *fmt, ...)

Aparte de ser variadic, nada raro. El problema es que GDB NO se romperá. He intentado todo lo que puedo pensar (punto de interrupción en la función, dentro de la función, antes de que se llame, lo que sea), pero tan pronto como mi programa está dentro de la función, recibo mensajes como "advertencia: error al eliminar el punto de interrupción" 0 "y GDB simplemente deja que el programa termine. Ya no hay nada de malo en eso (desde entonces he reparado el error que estaba tratando de encontrar, y todo funciona como debería), pero no puedo entrar en la función. Alguna idea sobre lo que podría causar esto?

Editar: ¡ Más información! GDB está configurando el punto de interrupción en 0x403057. La función comienza en 0x403025. Mira esta parte del desmontaje:

0x0000000000403053 <+46>: test %al,%al 0x0000000000403055 <+48>: je 0x403077 <cerror_at+82>

En este punto, se salta hacia adelante a 0x403077 (más allá del punto de interrupción). Verifiqué que colocar el punto de interrupción en una dirección antes de que funcione el "je", así como en una dirección en o después de 0x403077, el objetivo del salto, pero no en el medio (donde GDB intenta ubicarlo). ¿Por qué GDB colocaría el punto de interrupción en el medio de la función? Incluso GDB me dice que la dirección de la función es, de hecho, 0x403025.


Como se mencionó en los comentarios, debe intentar comprender qué código de máquina generó la compilación:

en GDB, puede ver el código de función real con disassemble cerror_at que debería dar algo como (x86_64):

(gdb) disassemble dive Dump of assembler code for function dive: 0x0000000000400504 <+0>: push %rbp 0x0000000000400505 <+1>: mov %rsp,%rbp 0x0000000000400508 <+4>: sub $0x10,%rsp 0x000000000040050c <+8>: mov %edi,-0x4(%rbp) 0x000000000040050f <+11>: mov -0x4(%rbp),%eax 0x0000000000400512 <+14>: add $0x1,%eax 0x0000000000400515 <+17>: mov %eax,%edi 0x0000000000400517 <+19>: callq 0x400504 <dive> 0x000000000040051c <+24>: leaveq 0x000000000040051d <+25>: retq End of assembler dump.

Luego verifique que la subrutina en realidad se llame: interrumpa la ejecución de algunas instrucciones antes de su llamada de función, luego:

(gdb) x/5i $p => 0x400539 <main+27>: mov $0x1,%esi 0x40053e <main+32>: mov %rax,%rdi 0x400541 <main+35>: callq 0x400408 <fwrite@plt> 0x400546 <main+40>: mov $0x1,%edi -->0x40054b <main+45>: callq 0x400504 <dive> <------

la salida debe ser ligeramente diferente con otra arquitectura de CPU, pero debería poder ver una instrucción de bifurcación apuntando a la dirección de su función.

-

Y puede ejecutar el maint info breakpoint justo antes del momento en que aparece Error removing breakpoint 0 para saber dónde se estableció el breakpoint 0 , podría ayudar a entender qué le pasa.


En función de su última edición, apuesto a que este es un error del compilador. Específicamente, apuesto a que hay un problema con la generación de información de depuración DWARF, que es lo que GDB usa para mapear direcciones entre el código del objeto y los archivos / procedimientos / números de línea en la fuente.

Puede intentar experimentar con -gdwarf-4 , -gdwarf-3 o incluso -gdwarf-2 para ver si hace alguna diferencia.

Si puede reducir esto a un simple caso de prueba, sospecho que los desarrolladores de gcc lo aceptarían como un error.

Por supuesto, esto también podría ser un error en GDB. Pero dado este comportamiento, creo que es menos probable.


Esto suena como un error en GDB. En particular, el Error removing breakpoint 0 es muy sospechoso (es un GDB de punto de interrupción insertado automáticamente en algún lugar; los puntos de corte insertados por el usuario tienen números positivos).

Probablemente deberías tratar de crear un caso de prueba reducido y presentar un error aquí .


Tal vez soy un poco denso, pero las razones más comunes que he encontrado para que un depurador se niegue a romper son las más simples.

  1. El código que intento depurar no coincide exactamente con el código del depurador.
  2. Olvidé compilar esa biblioteca con opciones de depuración.

Asegúrese de verificar estos dos en cualquier momento que obtenga un error de depuración como este, incluso si cree que no es el problema.