Νίκος Ντάρµος <ntarmos@cs.uoi.gr> Τµήµα Πληροφορικής Πανεπιστήµιο Ιωαννίνων Ιωάννινα, Μάιος 2010
Βασικές λειτουργίες ενός debugger: Εκτέλεση προγράµµατος ϐήµα-ϐήµα. Παρακολούθηση τιµών µεταβλητών. Εξέταση stack κλήσεων συναρτήσεων. «Κουτάκια» στον υπολογιστή... Απαιτείται µεταγλώττιση µε σύµβολα αποσφαλµάτωσης: Για GCC/GDB: user@host:...$ gcc test.c -g
user@host:...$ gcc test.c -S -o test.s test.s test.c int func(int arg) { return arg+1; } int main() { int i = 10; i = func(i); return i; } func: pushl movl movl addl popl ret main: pushl movl subl movl movl movl call movl movl leave ret %ebp %esp, %ebp 8(%ebp), %eax $1, %eax %ebp %ebp %esp, %ebp $20, %esp $10, -4(%ebp) -4(%ebp), %eax %eax, (%esp) func %eax, -4(%ebp) -4(%ebp), %eax
user@host:...$ gcc test.c -g -S -o test.s test.s func:.lfb0:.file 1 "test.c".loc 1 1 0.cfi_startproc.LVL0: pushl %ebp.lcfi0:.cfi_def_cfa_offset 8 movl %esp, %ebp.cfi_offset 5, -8.LCFI1:.cfi_def_cfa_register 5.loc 1 1 0 movl 8(%ebp), %eax addl $1, %eax.loc 1 3 0 popl %ebp ret.cfi_endproc main:.lfb1:.loc 1 4 0.cfi_startproc pushl %ebp.lcfi2:.cfi_def_cfa_offset 8 movl %esp, %ebp.cfi_offset 5, -8.LCFI3:.cfi_def_cfa_register 5 subl $4, %esp.loc 1 6 0 movl $10, (%esp) call func.loc 1 8 0 leave ret.cfi_endproc.llst0:.long.lfb0-.ltext0.long.lcfi0-.ltext0.value 0x2
Εκτέλεση Τερµατισµός/Επανεκκίνηση/ Εξοδος Απλή εκτέλεση προγράµµατος: user@host:...$ gdb a.out run Starting program: a.out Program exited with code 013. Εκτέλεση προγράµµατος µε παραµέτρους γραµµής εντολών: user@host:...$ gdb a.out set args arg1 "arg2" arg3 run user@host:...$ gdb a.out run arg1 "arg2" arg3
Εκτέλεση Τερµατισµός/Επανεκκίνηση/ Εξοδος Τερµατισµός/επανεκκίνηση εκτέλεσης: kill Kill the program being debugged? (y or n) y run ιακοπή/συνέχιση εκτέλεσης: <Ctrl+C> Program received signal SIGINT, Interrupt. main () at test.c:5 cont Εξοδος από τον gdb: quit The program is running. user@host:...$ Exit anyway? (y or n) y
Breakpoints Watchpoints Stepping Εισαγωγή breakpoints: break main Breakpoint 1 at 0x80483a5: file test.c, line 5. b test.c:6 Breakpoint 2 at 0x80483ac: file test.c, line 6. b func Breakpoint 3 at 0x8048397: file test.c, line 2. info breakpoints Num Type Disp Enb Address What 1 breakpoint keep y 0x080483a5 in main at test.c:5 2 breakpoint keep y 0x080483ac in main at test.c:6 3 breakpoint keep y 0x08048397 in func at test.c:2 Αφαίρεση/απενεργοποίηση breakpoints: del 1 disable 2 info breakpoints Num Type Disp Enb Address What 2 breakpoint keep n 0x080483ac in main at test.c:6 3 breakpoint keep y 0x08048397 in func at test.c:2
Breakpoints Watchpoints Stepping Watchpoints b main Breakpoint 1 at 0x80483a5: file test.c, line 5. watch i No symbol "i" in current context. r Starting program: /home/ntarmos/tmp/tests/a.out Breakpoint 1, main () at test.c:5 5 int i = 10; watch i Hardware watchpoint 2: i rwatch i Hardware read watchpoint 3: i awatch i Hardware access (read/write) watchpoint 4: i Οι µεταβλητές πρέπει να είναι στο scope!
Breakpoints Watchpoints Stepping Βηµατική εκτέλεση b main Breakpoint 1 at 0x80483a5: file test.c, line 5. r Starting program: a.out Breakpoint 1, main () at test.c:5 5 int i = 10; Γραµµή-γραµµή next 6 i = func(i); next 7 return i; Εντολή-εντολή step 6 i = func(i); step func (arg=10) at test.c:2 2 return arg+1;
Breakpoints Watchpoints Stepping Βηµατική εκτέλεση Ως το τέλος της συνάρτησης b func Breakpoint 1 at 0x8048397: file test.c, line 2. r Starting program: /home/ntarmos/tmp/tests/a.out Breakpoint 1, func (arg=10) at test.c:2 2 return arg+1; finish Run till exit from #0 func (arg=10) at test.c:2 0x080483b7 in main () at test.c:6 6 i = func(i); Value returned is $1 = 11 Κλήση συνάρτησης call printf("%d\n", i) 10 $2 = 3
Κώδικας Μεταβλητές Stack Core files Εξέταση Κώδικα list 1 int func(int arg) { 2 return arg+1; 3 } 4 int main() { 5 int i = 10; 6 i = func(i); 7 return i; 8 } 9
Κώδικας Μεταβλητές Stack Core files Εξέταση Μεταβλητών print i $1 = 10 disp i 1: i = 10 next 7 return i; 1: i = 11 Ανάθεση Μεταβλητών print i $1 = 10 set var i=20 p i $2 = 20
Κώδικας Μεταβλητές Stack Core files Εξέταση call stack b func Breakpoint 1 at 0x8048397: file test.c, line 2. r Starting program: /home/ntarmos/tmp/tests/a.out Breakpoint 1, func (arg=10) at test.c:2 2 return arg+1; bt #0 func (arg=10) at test.c:2 #1 0x080483b7 in main () at test.c:6
Κώδικας Μεταβλητές Stack Core files Μετακίνηση στο call stack frame #0 func (arg=10) at test.c:2 2 return arg+1; frame 1 #1 0x080483b7 in main () at test.c:6 6 i = func(i); down #0 func (arg=10) at test.c:2 2 return arg+1; up #1 0x080483b7 in main () at test.c:6 6 i = func(i);
Κώδικας Μεταβλητές Stack Core files Εξέταση τρέχοντος frame info frame Stack level 1, frame at 0xbfa8e360: eip = 0x80483b7 in main (test.c:6); saved eip 0xb7730b55 caller of frame at 0xbfa8e344 source language c. Arglist at 0xbfa8e358, args: Locals at 0xbfa8e358, Previous frame s sp is 0xbfa8e360 Saved registers: ebp at 0xbfa8e358, eip at 0xbfa8e35c info locals i = 10 info args No arguments. frame 0 #0 func (arg=10) at test-s.c:2 2 return arg+1; info args arg = 10
Κώδικας Μεταβλητές Stack Core files Ενεργοποίηση core files user:host:...$ ls a.out test.c user@host:...$./a.out Segmentation fault user:host:...$ ls a.out test.c user@host:...$ ulimit -c 0 user@host:...$ ulimit -c unlimited user@host:...$./a.out Segmentation fault (core dumped) user@host:...$ ls a.out core test.c
Κώδικας Μεταβλητές Stack Core files Χρησιµοποίηση core files user@host:...$ gdb a.out core user@host:...$ gdb a.out core core
Κώδικας Μεταβλητές Stack Core files segfault.c #include <stdlib.h> void func(int *ptr) { *ptr = 1; } void main() { int *p = NULL; func(p); }
Κώδικας Μεταβλητές Stack Core files user@host:...$ gcc segfault.c -g user@host:...$ ulimit -c unlimited user@host:...$./a.out Segmentation fault (core dumped) user@host:...$ gdb./a.out core Core was generated by./a.out. Program terminated with signal 11, Segmentation fault. [New process 2082] #0 0x0804839a in func (ptr=0x0) at segfault.c:4 4 *ptr = 1; bt #0 0x0804839a in func (ptr=0x0) at segfault.c:4 #1 0x080483ba in main () at segfault.c:9 p ptr $1 = (int *) 0x0
Κώδικας Μεταβλητές Stack Core files Βασικά ϐήµατα για γενικό debugging 1 Κάνω compile µε -g: user@host:...$ gcc myfile.c -g 2 Φορτώνω το πρόγραµµά µου στον gdb: user@host:...$ gdb a.out 3 Θέτω command-line arguments: set args arg1 arg2 arg3... 4 Θέτω breakpoints: b main b func... 5 Ξεκινώ την εκτέλεση: r 6 Συνεχίζω µε ϐηµατική εκτέλεση και έλεγχο µεταβλητών ενδιαφέροντος: p ptr n s...