GDB, sau (G)NU (D)e(B)ugger, este un utilitar ce poate fi folosit pentru a vedea ce se întâmplă înăuntrul unui program în timp ce acesta rulează sau pentru a putea vedea starea în care se află programul la momentul în care a crash-uit.
GDB este folosit în principal pentru a depana programe scrise în C sau C++. Acesta poate fi folosit în două moduri pentru a depana un program:
În acest laborator vom analiza doar prima modalitate de depanare.
Pentru exemplificare considerăm următorul program:
int add(int a, int b) { int c; c = a + b; return c; } int main(int argc, char **argv) { char *bug = 0; bug[2] = add(2, 4); return 0; }
După compilare, observăm că la executarea programului se produce un segmentation fault.
$ gcc bug.c -o bug $ ./bug Segmentation fault (core dumped)
gdb
este unealta potrivită pentru astfel de situații. Ca să aflăm la ce linie a avut loc acest segmentation fault, mai întâi trebuie să revenim la pasul de compilare și să activăm simbolurile de depanare folsind opțiunea -g
a compilatorului gcc
:
$ gcc -g bug.c -o bug
În continuare, rulăm programul folosind gdb
:
$ gdb bug [...] (gdb) run Program received signal SIGSEGV, Segmentation fault. 0x000000000040054f in main (argc=1, argv=0x7fffffffe038) at bug.c:13 13 bug[2] = add(2, 4); (gdb)
Simbolurile de depanare nu sunt în mod implicit adăugate deoarece prin adăugarea acestora, executabilul rezultat va avea o dimensiune mai mare. Folosiți opțiunea -g
doar în faza de dezvoltare.
$ gcc exemplu.c -o exemplu $ gcc -g exemplu.c -o exemplu_debug $ ls -l -rwxrwxr-x. 1 student student 6.0K Dec 7 23:55 exemplu -rwxrwxr-x. 1 student student 6.8K Dec 7 23:55 exemplu_debug
Câteva din comenzile de bază în gdb
sunt:
[...] (gdb) break main # adăugăm breakpoint în funcția main Breakpoint 1 at 0x400530: file bug.c, line 12. (gdb) run # pornim programul Starting program: /home/master/github/labs/ii/bug Breakpoint 1, main (argc=1, argv=0x7fffffffe038) at bug.c:12 12 char *bug = 0; (gdb) next # trecem la următoarea linie din codul sursă 13 bug[2] = add(2, 4); (gdb) next Program received signal SIGSEGV, Segmentation fault. 0x000000000040054f in main (argc=1, argv=0x7fffffffe038) at bug.c:13 13 bug[2] = add(2, 4); (gdb) run The program being debugged has been started already. Start it from the beginning? (y or n) y Starting program: /home/master/github/labs/ii/bug Breakpoint 1, main (argc=1, argv=0x7fffffffe038) at bug.c:12 12 char *bug = 0; (gdb) next 13 bug[2] = add(2, 4); (gdb) step # intrăm în funcția add pentru a o analiza pas cu pas add (a=2, b=4) at bug.c:6 6 c = a + b; (gdb) next 7 return c; (gdb) next 8 } (gdb) next Program received signal SIGSEGV, Segmentation fault. 0x000000000040054f in main (argc=1, argv=0x7fffffffe038) at bug.c:13 13 bug[2] = add(2, 4); (gdb) quit A debugging session is active. Inferior 1 [process 331] will be killed. Quit anyway? (y or n) y
#include <stdio.h> #include <stdbool.h> #define MAX 7 #define MAGIC 100000 int intArray[MAX] = {4,6,3,2,1,9,7}; void printline(int count) { int i; for(i = 0;i <count-1;i++) { printf("="); } printf("=\n"); } void display() { int i; printf("["); // navigate through all items for(i = 0;i<MAX;i++) { printf("%d ",intArray[i]); } printf("]\n"); } void swap(int num1, int num2) { int temp = intArray[num1]; intArray[num1+MAGIC] = intArray[num2]; intArray[num2] = temp; } int partition(int left, int right, int pivot) { int leftPointer = left -1; int rightPointer = right; while(true) { while(intArray[++leftPointer] < pivot) { //do nothing } while(rightPointer > 0 && intArray[--rightPointer] > pivot) { //do nothing } if(leftPointer >= rightPointer) { break; } else { printf(" item swapped :%d,%d\n", intArray[leftPointer],intArray[rightPointer]); swap(leftPointer,rightPointer); } } printf(" pivot swapped :%d,%d\n", intArray[leftPointer],intArray[right]); swap(leftPointer,right); printf("Updated Array: "); display(); return leftPointer; } void quickSort(int left, int right) { if(right-left <= 0) { return; } else { int pivot = intArray[right]; int partitionPoint = partition(left, right, pivot); quickSort(left,partitionPoint-1); quickSort(partitionPoint+1,right); } } int main() { printf("Input Array: "); display(); printline(50); quickSort(0,MAX-1); printf("Output Array: "); display(); printline(50); }