Un artículo para aprender el principio y el uso de la herramienta de depuración de GDB

Artículo de referencia: https://blog.csdn.net/weixin_55953651/article/details/126908125

1. El principio de la herramienta de depuración de GDB

1.1 No se realiza la depuración del proceso

Cuando la depuración de gdb está habilitada y se ejecuta gdb ./test, suceden muchas cosas complicadas en el sistema operativo. El sistema primero iniciará el proceso gdb, que llamará a la función del sistema fork() para crear un proceso secundario. Este proceso secundario no dos cosas importan:

  • Llame a la función del sistema ptrace(PTRACE_TRACEME, [otros parámetros]);
  • La prueba del programa ejecutable se carga y ejecuta a través de exec, luego el programa de prueba comienza a ejecutarse en este subproceso.

Por favor agregue una descripción de la imagen

1.2 Depuración durante la ejecución

Si desea depurar un proceso ya ejecutado, debe llamar a ptrace(PTRACE_ATTACH, [otros parámetros]) en el proceso padre de gdb. En este momento, el proceso gdb se adjuntará (vinculará) al proceso B ya ejecutado, gdb Adoptar el proceso B como su propio proceso secundario, y el comportamiento del proceso secundario B es equivalente a una operación PTRACE_TRACEME. En este momento, el proceso gdb enviará una señal SIGSTO al proceso secundario B. Después de que el proceso secundario B reciba la señal SIGSTOP, suspenderá la ejecución e ingresará al estado TASK_STOPED, lo que indica que está listo para ser depurado.

Por favor agregue una descripción de la imagen

1.3 Introducción al prototipo de llamada al sistema gdb

#include <sys/ptrace.h>

long ptrace(enum __ptrace_request request, pid_t pid, void *addr, void *data);

La función ptrace system es una llamada al sistema proporcionada por el kernel de Linux para el seguimiento de procesos, a través de ella un proceso (gdb) puede leer y escribir el espacio de instrucciones, el espacio de datos, la pila y los valores de registro de otro proceso (prueba) . Además, el proceso gdb se hace cargo de todas las señales del proceso de prueba, es decir, todas las señales enviadas por el sistema al proceso de prueba son recibidas por el proceso gdb, de esta forma se controla la ejecución del proceso de prueba. por gdb, para lograr el propósito de depuración.

Cada parámetro se explica a continuación:

  1. enum __ptrace_request request: es un tipo enumerado utilizado para especificar el tipo de operación a realizar. Este parámetro le dice ptracea la función qué tipo de operación de seguimiento se realizará en el proceso, como registro de lectura, tipo de escritura, que define una serie de constantes del tipo de solicitud de seguimiento. Por ejemplo, PTRACE_ATTACHsignifica adjuntar a un nuevo proceso, PTRACE_GETREGSsignifica obtener valor de registro. Los principales tipos de solicitudes son los siguientes:
PTRACE_TRACEME:用于将当前进程标记为被跟踪的目标。调用进程使用这个类型请求后,它的父进程可以使用 PTRACE_ATTACH 来附加到它,对其进行调试和跟踪。
PTRACE_ATTACH:用于将一个进程附加到另一个进程上进行调试和跟踪。调试器进程可以使用这个类型请求,通过指定目标进程ID来附加到目标进程。
PTRACE_DETACH:用于从一个已经被附加和调试的进程上分离调试器。这个请求会停止对目标进程的跟踪,并将其恢复为正常运行状态。
PTRACE_PEEKDATA:用于从目标进程的内存中读取数据。可以使用该请求来读取目标进程的内存值,例如寄存器、栈帧等。
PTRACE_POKEDATA:用于向目标进程的内存中写入数据。可以使用该请求来修改目标进程的内存值,例如修改寄存器、改变变量值等。
PTRACE_GETREGS:用于获取目标进程的寄存器值。通过这个请求,可以获得目标进程的 CPU 寄存器的当前值,用于调试和跟踪。
PTRACE_SETREGS:用于设置目标进程的寄存器值。通过这个请求,可以将特定的寄存器值设置为目标进程中的特定值。
PTRACE_CONT:用于继续执行已附加的目标进程。调试器进程可以使用这个请求来继续目标进程的执行,直到下一个断点或者其他事件触发。
  1. pid_t pid: Es de tipo entero, indicando el ID de proceso (PID) del proceso de destino a operar. pidEspecifica qué proceso rastrear, que puede ser el proceso actual, otros procesos en ejecución o procesos secundarios, etc.
  2. void *addr: Es un tipo de puntero, usado para especificar la dirección de memoria, y el uso específico depende de diferentes requestparámetros. Por ejemplo, para algunas solicitudes de lectura y escritura de memoria, addrse especifica la dirección de memoria que se va a leer o escribir.
  3. void *data: Es un tipo de puntero, utilizado para transferir datos, y el uso específico depende de diferentes requestparámetros. Para algunas solicitudes de lectura y escritura de memoria o registros, datase especifica la ubicación de almacenamiento de datos que se va a leer o escribir.

ptraceLa función devuelve un longvalor de tipo que indica el resultado de la operación o un código de error. Por lo general, un valor de retorno mayor o igual a 0 indica éxito y menor a 0 indica que ocurrió un error.

Si no hay depuración de gdb, el sistema operativo y el proceso de destino interactúan directamente; si se usa gdb para depurar el programa, gdb interceptará la señal enviada por el sistema operativo al proceso de destino, y gdb decidirá de acuerdo con el atributo de la señal: continuar ejecutándose Si el programa de destino transfiere la señal actualmente interceptada al programa de destino, de modo que el programa de destino realice las acciones correspondientes bajo el comando de la señal enviada por gdb.

imagen-20230726111320295

En segundo lugar, el uso de herramientas de depuración de GDB

2.1 Iniciar la depuración

Antes de que el programa comience a depurar, asegúrese de que el programa tenga la siguiente opción -g para agregar información de depuración al compilar con gcc y g++

gcc -g test.c -o test

1. Inicie un programa que no se está ejecutando

Para iniciar un programa que no se está ejecutando, simplemente use el siguiente comando en el directorio del programa correspondiente

gdb test

2. Depurar el proceso del programa que ha comenzado a ejecutarse.

Para depurar un proceso de programa en ejecución, primero use el comando superior para ver el pid del proceso de programa en ejecución de la siguiente manera:

imagen-20230730231037766

Por ejemplo, el pid del programa qemu-system-x86 que quiero cargar es 269427, luego use el siguiente comando para adjuntar el proceso a la depuración de GDB

gdb attach 269427#gdb attach [进程号]

O abra gdb primero e ingrese el adjunto 269427 en gdb. El efecto es el siguiente

imagen-20230726180838421

En este momento, el programa está en estado de pausa, use el siguiente comando para que el programa continúe ejecutándose

#前面是缩写,#后是全写,两者皆可
(gdb) c#continue

El efecto es el siguiente:

imagen-20230726181136712

2.2 Gestión de Puntos de Interrupción

añadir punto de interrupción

  • método uno
#源程序只有一个文件
b [行号]#break [行号]
  • Método dos
#源程序多个个文件
b [文件名.c]:[行号]#break [文件名.c]:[行号]

Después de agregar un punto de interrupción, se ve así:

imagen-20230726181712075

ver todos los puntos de interrupción

info b#info break

El efecto es el siguiente:

imagen-20230726181824992

Podemos ver todos los puntos de interrupción y los números de punto de interrupción

eliminar punto de interrupción

delete#删除所有断点
delete [断点编号]#删除指定断点

2.3 Interrupción de la ejecución de depuración

s#step 单步执行,进入函数调用
n#next 逐行执行当前线程的代码,不进入函数调用
c#continue 执行代码到下一个断点
f#finish 执行完当前函数并跳出
ignore [断点号] [次数]#设置或修改运行时断点的忽略计数

2.4 Vigilancia de parámetros de funcionamiento

p [变量名]#print [变量名] 输出该变量的值
display [变量名]#调试运行的每一步自动输出该变量的值
bt#显示当前的函数调用堆栈情况
list [行数]#显示当前执行的代码,默认10行
watch [变量名]#设置变量监视点,在变量值改变时暂停程序。

info breakpoints#显示当前已设置的断点列表。
info watchpoints#显示当前已设置的监视点(观察点)列表。
info functions#显示程序中定义的所有函数列表。
info variables#显示程序中定义的所有全局变量和静态变量列表。
info locals#显示当前函数的局部变量信息。
info args#显示当前函数的参数信息。
info threads#显示当前正在运行的所有线程信息。
info registers#显示当前线程的寄存器值。
info frame#显示当前的调用帧信息。
info sharedlibrary#显示加载的共享库信息。
info inferior#显示当前程序的执行状态信息。
info record#显示反复执行的命令数量。
info breakpoints location <address>#显示指定地址上设置的断点信息。
info break <breakpoint_number>#显示指定编号的断点信息。
info line <filename>:<line>#显示指定文件和行号的源代码信息。

2.5 Depuración de subprocesos múltiples

info thread#命令查看当前线程的信息
info threads#命令查看当前所有线程
frame [栈帧号] #命令切换到指定的栈帧
thread [线程号]#切换到指定线程

Supongo que te gusta

Origin blog.csdn.net/qq_40959462/article/details/131995352
Recomendado
Clasificación