This shows you the differences between two versions of the page.
ii:lab:laborator4 [2016/12/08 00:06] iulian_gabriel.radu [Rulare GDB] |
ii:lab:laborator4 [2016/12/08 10:03] (current) iulian_gabriel.radu [Exerciții și aplicații] |
||
---|---|---|---|
Line 7: | Line 7: | ||
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: | 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 | + | * rulându-l folosind comanda gdb |
- | - folosind fişierul core generat în urma unei erori grave (de obicei segmentation fault) | + | * folosind fişierul core generat în urma unei erori grave (de obicei segmentation fault) |
În acest laborator vom analiza doar prima modalitate de depanare. | În acest laborator vom analiza doar prima modalitate de depanare. | ||
Line 69: | Line 69: | ||
===== Comenzi de bază GDB ===== | ===== Comenzi de bază GDB ===== | ||
- | TODO | + | 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 ===== | ===== Exerciții și aplicații ===== | ||
- | - Folosiți gdb pentru a depana următorul program C: <code c divide.c> | + | - <code c divide.c> |
#include <stdio.h> | #include <stdio.h> | ||
Line 96: | Line 150: | ||
return 0; | return 0; | ||
}</code> | }</code> | ||
- | - TODO | + | |
+ | - <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> | ||