2010-11-25 11 views
3

Ich bin auf Linux mit Gdb-Version 6.8-debian. Ich war neugierig darauf, wie die Hauptfunktion in einem C-Programm ausgeführt wird und herumspielt und an verschiedenen Stellen sucht, ich habe gelernt, dass dafür die Funktion __libc_start_main zuständig ist. Die Argumente für __libc_start_main sind unter anderem: Die Adresse von main (wie wir von c wissen, der Pfad ist immer als argv [0] angegeben), der nächste argc, der im Register ESI liegen sollte, und die nächste Adresse von argv, die sein sollte in ECX.Zugriff auf Kommandozeilenargumente mit gdb

rumspielen habe ich das folgende einfache Programm, cmdargs.c, die einfach gibt das erste Argument Befehlszeile beim Start gegeben:

#include <stdio.h> 
#include <stdlib.h> 

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

Jetzt beginne ich zu debuggen cmdargs und einen Haltepunkt auf der Haupt gesetzt und __libc_start_main (info von Start-gDB entfernt):

gdb cmdargs

(gdb) b main 
Breakpoint 1 at 0x80483d2 
(gdb) b __libc_start_main 
Breakpoint 2 at 0xb7f3f5a8 
(gdb) r qwerty 

Hier traf ich den Haltepunkt 2 in __libc_start_main und kann sehen argc und argv [0] mit

(gdb) p $esi 

und

(gdb) x/s *($ecx) 

Das funktioniert wie erwartet, aber wie kann ich auf dem ersten nicht-implizite Kommandozeilenargument "qwerty"? Ich habe versucht, bis zum Breakpoint bei main weiterzumachen und einzutreten, aber argc und argv werden nicht erkannt (Warum?). Kann mir jemand sagen, was los ist?

Breakpoint 1, 0x080483d2 in main() 
(gdb) stepi 
0x080483d5 in main() 
(gdb) p argc 
No symbol "argc" in current context. 
(gdb) p argv 
No symbol "argv" in current context. 
(gdb) 

Antwort

1

Die Ausgabe sieht aus, als ob Sie nicht genug Debuginformationen haben. GDB sollte nicht nur Adressen, sondern auch Zeilennummern drucken.

(gdb) b main 
Breakpoint 1 at 0x400543: file test.c, line 3. 
(gdb) r test1 test2 
Starting program: /home/simon/a.out test1 test2 

Breakpoint 1, main (argc=3, argv=0x7fffffffdca8) at test.c:3 
3    puts("blabla"); 
(gdb) print argc 
$1 = 3 
(gdb) print argv 
$2 = (char **) 0x7fffffffdca8 
(gdb) print argv[0] 
$3 = 0x7fffffffe120 "/home/simon/a.out" 
(gdb) print argv[1] 
$4 = 0x7fffffffe132 "test1" 
(gdb) print argv[2] 
$5 = 0x7fffffffe138 "test2" 
(gdb) 
1

sollten Sie die -g Optionen gcc hinzufügen, die es zu bauen sagt auch Debug-Informationen ..

1

Yep, Ihr Problem ist der Mangel an Symbolen, nicht bei der Kompilierung enthalten.

mit Debug-Informationen zu kompilieren:

$ gcc -g3 cmdargs.c -o cmdargs 

Dann:

$ gdb ./cmdargs 
... 
Reading symbols from ./cmdargs...done. 
(gdb) b main 
Breakpoint 1 at 0x400545: file cmdargs.c, line 6. 
(gdb) r 
Starting program: cmdargs 

Breakpoint 1, main (argc=1, argv=0x7fffffffdc28) at cmdargs.c:6 
6  printf("%s: %s\n", "argv[1]", *++argv); 
(gdb) p argc 
$1 = 1 
(gdb) p argv 
$2 = (char **) 0x7fffffffdc28 
(gdb) p *argv 
$3 = 0x7fffffffe00c "/home/jcgonzalez/cmdargs" 

See, haben Sie jetzt Zugriff auf die Symbole bekommen (sie erkannt werden), sowie die Zeilennummern. Wie in Let_Me_Be gezeigt, können Sie auf einzelne Array-Elemente mit der Array [n] -Notation zugreifen, aber Sie können auch alle Befehlszeilenargumente auf einmal (einschließlich der [0] -ed) mit der * array @ times-Notation anzeigen. Beachten Sie, dass das erste Argument im folgenden Beispiel eine Zeichenfolge in Anführungszeichen ist:

(gdb) set args "this is an argument" these are four more 
(gdb) r 
Starting program: cmdargs "this is an argument" these are four more 

Breakpoint 1, main (argc=6, argv=0x7fffffffdbd8) at cmdargs.c:6 
6  printf("%s: %s\n", "argv[1]", *++argv); 
(gdb) p argc 
$4 = 6 
(gdb) p *[email protected]          
$5 = {0x7fffffffdfe6 "/home/jcgonzalez/cmdargs", 0x7fffffffdfff "this is an argument", 0x7fffffffe012 "these", 0x7fffffffe017 "are", 0x7fffffffe01b "four", 
    0x7fffffffe020 "more"} 
(gdb) p argv[1] 
$6 = 0x7fffffffdfff "this is an argument" 
(gdb) p argv[2] 
$7 = 0x7fffffffe012 "these"