This shows you the differences between two versions of the page.
ii:lab:laborator4 [2016/12/08 00:40] iulian_gabriel.radu [Comenzi de bază 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 70: | Line 70: | ||
Câteva din comenzile de bază în ''gdb'' sunt: | Câteva din comenzile de bază în ''gdb'' sunt: | ||
- | * **b[reakpoint]** - 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). | + | * **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). |
- | * **n[ext]** - 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. | + | * **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. |
- | * **s[tep]** - se "pășește" în interiorul funcții pentru inspectarea ei. | + | * **step** - se "pășește" în interiorul funcții pentru inspectarea ei. |
- | * **fin[ish]** - se iese din funcţia curentă. | + | * **finish** - se iese din funcţia curentă. |
- | * **q[uit]** - se părăsește shell-ul gdb | + | * **quit** - se părăsește shell-ul gdb |
<code bash> | <code bash> | ||
Line 120: | Line 120: | ||
Quit anyway? (y or n) y | Quit anyway? (y or n) y | ||
</code> | </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 146: | 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> | ||