Differences

This shows you the differences between two versions of the page.

Link to this comparison view

ii:lab:laborator4 [2016/10/02 18:01]
alexandru.radovici
ii:lab:laborator4 [2016/12/08 10:03] (current)
iulian_gabriel.radu [Exerciții și aplicații]
Line 1: Line 1:
-====== Laborator 4 - Phaser ​======+====== Laborator 4 - GDB ====== 
 + 
 +===== Introducere ===== 
 + 
 +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: 
 + 
 +  * rulându-l folosind comanda gdb 
 +  * folosind fişierul core generat în urma unei erori grave (de obicei segmentation fault) 
 + 
 +În acest laborator vom analiza doar prima modalitate de depanare. 
 + 
 +===== Rulare GDB ===== 
 + 
 +Pentru exemplificare considerăm următorul program: 
 + 
 +<code c bug.c> 
 +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; 
 +
 +</​code>​ 
 +După compilare, observăm că la executarea programului se produce un segmentation fault. 
 + 
 +<code bash> 
 +$ gcc bug.c -o bug 
 +$ ./bug 
 +Segmentation fault (core dumped) 
 +</​code>​ 
 + 
 +''​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'':​ 
 + 
 +<code bash> 
 +$ gcc -g bug.c -o bug 
 +</​code>​ 
 + 
 +În continuare, rulăm programul folosind ''​gdb'':​ 
 +<code bash> 
 +$ 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) 
 +</​code>​ 
 + 
 +<note important>​ 
 + 
 +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 
 + 
 +</​note>​ 
 + 
 +===== Comenzi de bază GDB ===== 
 + 
 +Câteva din comenzile de bază în ''​gdb''​ sunt: 
 +  * **breakpoint** - primeşte ca argument un nume de funcţie (ex: main), un număr de linie şi, eventual, un fişier (ex: break sursa.c:​50),​ o funcţie (b sursa.c:​my_function) sau o adresă (ex: breakpoint *0x80483d3).  
 +  * **next** - va continua execuţia programului până ce se va ajunge la următoarea linie din codul sursă. Dacă linia de executat conţine un apel de funcţie, funcţia se va executa complet.  
 +  * **step** - se "​pășește"​ în interiorul funcții pentru inspectarea ei. 
 +  * **finish** - se iese din funcţia curentă. 
 +  * **quit** - se părăsește shell-ul gdb 
 + 
 +<code bash> 
 +[...] 
 +(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 
 +</​code>​ 
 + 
 +  * **print** - cu ajutorul acesteia se pot afişa valorile variabilelor din funcţia curentă sau a variabilelor globale. print poate primi ca argument şi expresii complicate (dereferenţieri de pointeri, referenţieri ale variabilelor,​ expresii aritmetice, aproape orice expresie C validă). În plus, print poate afişa structuri de date precum struct şi union sau evalua funcţii şi întoarcerea rezultatului lor. 
 +  * **list** - afișează o parte din fișierul sursă al programulu debanat. 
 +  * **backtrace** - afișează un backtrace. Un backtrace afișează, în ordine inversă, funcțiile ce au fost apelate pentru a se ajunge la linia curentă.  
 + 
 +===== Exerciții și aplicații ===== 
 + 
 +  - <code c divide.c>​ 
 +#include <​stdio.h>​ 
 + 
 +int divide(int a, int b) 
 +
 +    printf("​Dividing %d by %d\n", a, b); 
 +    return a / b; 
 +
 + 
 +int main(void) 
 +
 +    int x, y, result; 
 + 
 +    x = 10; y = 2; 
 +    result = divide(x, y); 
 +    printf("​%d\n",​ result); 
 + 
 +    x = 5; y = 0; 
 +    result = divide(x, y); 
 +    printf("​%d\n",​ result); 
 + 
 +    return 0; 
 +}</​code>​ 
 + 
 +  - <code c quick.c>​ 
 +#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);​ 
 +}</​code>​ 
ii/lab/laborator4.1475420502.txt.gz · Last modified: 2016/10/02 18:01 by alexandru.radovici
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0