2008-12-18 9 views
15

J'ai une application linux C (A) qui engendre un autre processus (P) quand il est démarré. Quand je veux déboguer le PI start A comme d'habitude et je me connecte avec ddd/gdb à P.Comment déboguer le point d'entrée du processus fork-exec dans GDB?

Des problèmes apparaissent quand je veux déboguer le point d'entrée (début de main) de P. Si je suis l'approche habituelle quand Je connecte le débogueur à P est déjà à la fin. La solution que j'ai trouvée était d'insérer un sommeil au début de la partie principale de P donc j'ai le temps de me connecter avec gdb mais ce n'est pas une solution très élégante.

J'ai également essayé d'utiliser asm("int $3") mais cela ne semble pas fonctionner.

Avez-vous une idée de comment je pourrais résoudre ce problème? (de préférence sans modifier le code de A ou P)

Répondre

19

Vous devez utiliser cette option:

set follow-fork-modemode

Lorsque le mode est l'un des parent, child ou ask.

Pour suivre le parent (valeur par défaut) utiliser:

set follow-fork-mode parent 

Pour suivre l'enfant:

set follow-fork-mode child 

Pour que le débogueur vous demander à chaque fois:

set follow-fork-mode ask 

Donc, fondamentalement, vous commencerez à connecter gdb à A, puis définissez gdb pour suivre l'enfant, puis, lorsque A engendrera P, gdb se connectera P et détachez de A.

0

Vous devriez être en mesure de le faire en utilisant les fonctions de débogage à distance de gdb, en particulier gdbserver. En effet, lancez (P) en utilisant gdbserver. Ces liens ont des informations plus détaillées:

+0

gdbserver permet le débogage à distance, mais ne résout pas le problème en cours, ce qui est plus un cas de GDB suit fork/clone. –

+0

Je ne pense pas que ce soit un cas pour le débogage à distance. Il s'agit plus de savoir quel processus gdb suit sur une fourche. –

6

En plus du Nathan Fellman's answer, catchpoints sont très pratiques, i.g .:

catch exec 

Catchpoint fonctionne comme un point d'arrêt. Chaque fois qu'un appel à exec() syscall est détecté, GDB s'arrête. Cela vous permet de définir n'importe quel point d'arrêt (par exemple break main) dans tout fichier exécutable nouvellement chargé avant de continuer. Un autre point d'accès catch fork fonctionne de manière similaire pour fork() détection syscall.

Il est particulièrement pratique:

  • lorsque les deux parents et de l'enfant doit être suivi (set detach-on-fork off);
  • lorsque les processus parent forks chargent souvent divers exécutables.
-1

Définir un point d'arrêt à main(), il va également casser à main() du programme exécuté.

+1

Non, ce ne sera pas :( –

0

exec partie avec file + break main

La fourche faisait partie a été expliqué à: https://stackoverflow.com/a/377295/895245

Maintenant pour le exec:

a.c:

#include <unistd.h> 

int main(void) { 
    execl("./b", "./b", "ab", "cd", (char*)NULL); 
    return 1; 
} 

b.c:

#include <stdio.h> 

int main(int argc, char **argv) { 
    printf("%s\n", argv[0]); 
    printf("%s\n", argv[1]); 
} 

Puis:

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

maintenant sur la session interactive:

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) 

il vous suffit de vous assurer que vous allez à la exec avant le fichier en cours d'exécution, peut-être avec un b execl , car après cela, vous utiliserez des symboles du nouveau fichier.

Testé dans Ubuntu 14.04, gdb 7.7.1.

Questions connexes