Cómo utilizar GDB para depurar archivos principales
Además, aunque el valor predeterminado es este, también puede escribir su propia función de procesamiento de señales para cambiar el comportamiento predeterminado. Para obtener más información sobre las señales, consulte el enlace de referencia 33. El contenido anterior es solo una condición necesaria para generar coredump, pero no una condición suficiente. La generación de archivos principales también depende del shell en el que se ejecuta el programa. Puede usar el comando ulimit -a para ver el resultado. El resultado es aproximadamente el siguiente: sagi@sagi-laptop:~$ ulimit -a tamaño del archivo principal (. bloques, -c) 0 tamaño de segmento de datos (kbytes, -d) programación de prioridad ilimitada (-e) 20 tamaño de archivo (bloques, -f) señal pendiente ilimitada (-i) 16382 memoria máxima bloqueada (kbytes, -l) 64 máx tamaño de memoria (kbytes, -m) archivos abiertos ilimitados ( -n) 1024 tamaño de tubería (512 bytes. -p) 8 mensajes POSIX, -p) 8 cola de mensajes POSIX (bytes, -q) 819200 prioridad en tiempo real (-r ) 0 tamaño de pila (kilobytes, -s) 8192 Tiempo de CPU (segundos, -t) Procesos de usuario máximos ilimitados (-u) Memoria virtual ilimitada (kilobytes, -v) Bloqueos de archivos ilimitados (-x) Ilimitado ¿Ves esa primera línea? Tamaño del archivo principal, este valor se utiliza para limitar el tamaño del archivo principal generado; si excede este valor, no se guardará. Mi resultado aquí es 0, lo que significa que el archivo principal no se guardará, e incluso si se genera, no se guardará ==. Para cambiar esta configuración, use ulimit -c unlimited. Bien, ahora tenemos todo lo que necesitamos, excepto el programa para generar el kernel, que es demasiado simple para los programadores de C. #include ; #include ; int crash() { char *xxx = "crash!!!"; xxx[1] = 'D'; // Escribe almacenamiento de solo lectura } int foo() { return crash (); } int main() { return foo(); } Comenzando con la depuración El programa anterior debe compilarse con el parámetro -g para que el archivo ejecutable generado contenga suficiente información de depuración. Después de compilar y ejecutar el programa, debería ver el esperado "Error de segmento (núcleo volcado)" o "Error de segmento (núcleo volcado)". Busque el archivo core o core.xxx en el directorio actual. Usaremos el clásico depurador de Linux GDB para cargar un programa con un archivo principal: gdb exefile core. Cabe señalar que el archivo principal debe generarse mediante un archivo exe; de lo contrario, la tabla de símbolos no coincidirá. El resultado después de la carga es el siguiente: sagi@sagi-laptop:~$ gdb coredump core El núcleo fue generado por ./coredump'. El programa finaliza con la señal 11, fallo de segmentación. #0 0x080483a7 en crash () en coredump.c:8 8 xxx[1] = 'D'; (gdb) Podemos ver que podemos encontrar directamente el kernel de salida y escribir una región de memoria de solo lectura en la línea 8, lo que provoca se activará una señal de fallo de segmentación. Hay un pequeño truco al cargar el kernel. Si no sabe de antemano qué programa generó el archivo del kernel, puede encontrar un reemplazo primero. Por ejemplo, /usr/bin/w es una buena opción.
Por ejemplo, si cargamos el núcleo generado anteriormente usando este método, gdb tendrá una salida similar a: sagi@sagi-laptop:~$ gdb /usr/bin/w core El núcleo fue generado por ./coredump'. El programa finaliza con la señal 11, fallo de segmentación. #0 0x080483a7 en ? () (gdb) Puede ver que GDB le ha preguntado qué programa generó este kernel. Operaciones comunes de GDB Los procedimientos anteriores son relativamente simples y no se requieren operaciones adicionales para detectar problemas. Pero esta no es la situación real. Por lo general, se requiere un seguimiento de un solo paso, el establecimiento de puntos de interrupción, etc., para localizar el problema con éxito. Algunas operaciones comunes del BGF se enumeran a continuación. Iniciar programa: ejecutar
Establecer punto de interrupción: b número de línea | nombre de función
Eliminar punto de interrupción: eliminar número de punto de interrupción
Deshabilitar punto de interrupción: deshabilitar número de punto de interrupción
Habilitar punto de interrupción: habilitar número de punto de interrupción
Seguimiento de un solo paso: siguiente también se puede abreviar como n
Seguimiento de un solo paso. el paso también se puede abreviar como s
Seguimiento de un solo paso: el paso también se puede abreviar como s
Imprimir variable: imprimir nombre de variable
Establecer variable: establecer var= valor
Ver tipo de variable: ptype var
Ejecutar secuencialmente hasta el final: cont
Ejecutar secuencialmente hasta una línea: util linenoImprime información de la pila: bt