que procesos proceso manejo hijo funcion execve execlp entre ejemplos comunicacion c linux gdb

procesos - ¿Cómo depurar el punto de entrada del proceso fork-exec en GDB?



procesos en c (5)

Tengo una aplicación C linux (A) que genera otro proceso (P) cuando se inicia. Cuando quiero depurar PI inicio A como de costumbre y me conecto con ddd / gdb a P.

Los problemas aparecen cuando quiero depurar el punto de entrada (inicio de main) de P. Si sigo el enfoque habitual cuando conecto el depurador a P ya es tarde. La solución que encontré fue insertar un sueño al principio de la parte principal de P, así que tengo tiempo para conectarme con gdb, pero esta no es una solución muy elegante.

También intenté usar asm("int $3") pero parece que no funciona.

¿Tienes alguna idea de cómo podría resolver este problema? (preferiblemente sin alterar el código de A o P)


Debería poder hacerlo haciendo uso de las funciones de depuración remota de gdb, específicamente gdbserver . En efecto, inicie (P) usando gdbserver . Estos enlaces tienen información más detallada:


establecer un punto de interrupción en main (), también se romperá en main () del programa ejecutado.


Deberías usar esta opción:

set follow-fork-mode mode

Donde el modo es uno de los parent , child o ask .

Para seguir el padre (este es el valor predeterminado), use:

set follow-fork-mode parent

Para seguir al niño:

set follow-fork-mode child

Para que el depurador le pregunte cada vez:

set follow-fork-mode ask

Así que básicamente comenzarías conectando gdb a A, luego configura gdb para seguir al niño, y luego cuando A engendra P, gdb se conectará a P y se separará de A.


Además de la respuesta de Nathan Fellman , los puntos de captura son útiles, ig:

catch exec

Catchpoint funciona como un punto de interrupción. Cada vez que se detecta una llamada a syscall exec () , GDB se detiene. Esto le permite establecer cualquier punto de interrupción (ig break main ) en cualquier ejecutable recién cargado antes de continuar. Otra bifurcación de catch fork catchpoint funciona de forma similar para la detección de syscall fork () .

Es especialmente conveniente:

  • cuando se deben seguir tanto al padre como al hijo ( set detach-on-fork off );
  • cuando el padre procesa las horquillas a menudo cargando varios ejecutables.

exec parte con file + break main

El tenedor fue parte se explicó en: https://.com/a/377295/895245

Ahora para el exec :

C.A:

#include <unistd.h> int main(void) { execl("./b", "./b", "ab", "cd", (char*)NULL); return 1; }

antes de Cristo:

#include <stdio.h> int main(int argc, char **argv ) { printf("%s/n", argv[0]); printf("%s/n", argv[1]); }

Entonces:

gcc -g a.c -o a gcc -g b.c -o b gdb -nh -q a

Ahora en la sesión interactiva:

Reading symbols from a...done. (gdb) start Temporary breakpoint 1 at 0x4004ea: file a.c, line 4. Starting program: /home/cirsan01/test/gdb-exec/a Temporary breakpoint 1, main () at a.c:4 4 execl("./b", "./b", "ab", "cd", (char*)NULL); (gdb) file b A program is being debugged already. Are you sure you want to change the file? (y or n) y Load new symbol table from "b"? (y or n) y Reading symbols from b...done. (gdb) b main Breakpoint 2 at 0x4004f5: file b.c, line 4. (gdb) n Breakpoint 2, main (argc=0, argv=0x7fffffffa570) at b.c:4 4 printf("%s/n", argv[1]); (gdb) n process 4877 is executing new program: /home/cirsan01/test/gdb-exec/b Breakpoint 2, main (argc=3, argv=0x7fffffffa598) at b.c:4 4 printf("%s/n", argv[1]); (gdb) n ab 5 printf("%s/n", argv[2]); (gdb) n cd 6 } (gdb)

Solo tiene que asegurarse de ir al ejecutable antes de ejecutar el archivo, posiblemente con un exec b execl , ya que después de eso, utilizará símbolos del nuevo archivo.

Probado en Ubuntu 14.04, gdb 7.7.1.