Differences

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

Link to this comparison view

programare:debugging [2016/10/31 08:34]
laura.vasilescu [Segmentation fault / stack smashing detected]
programare:debugging [2016/10/31 08:57] (current)
laura.vasilescu [Warning-uri de compilare]
Line 30: Line 30:
  
 Warning-urile pot duce la rezultate eronate. Exemplu de posibile warning-uri:​ Warning-urile pot duce la rezultate eronate. Exemplu de posibile warning-uri:​
 +  * folosirea unei variabile neinițializate
   * atribuirea de număr cu semn unui întreg fără semn   * atribuirea de număr cu semn unui întreg fără semn
   * cast-uri de la int la char (deci cu diminuare de spațiu)   * cast-uri de la int la char (deci cu diminuare de spațiu)
Line 41: Line 42:
 ==== Segmentation fault / stack smashing detected ==== ==== Segmentation fault / stack smashing detected ====
  
 +Erorile de genul aceasta înseamnă, pe scurt, că undeva faceți un acces nevalid de memorie. Cel mai frecvent, cauza poate să fie una din următoarele:​
 +  * accesați printr-un indice un element într-un vector nealocat (exemplu: dacă vectorul a fost declarat //int v[100]//, iar voi accesați //v[100]// sau chiar cu un indice mai mare sau cu unul negativ)
 +  * folosiți o funcție recursivă care nu are condiție de oprire, sau condiția acesteia nu funcționează corect sau nu acoperă cazul din testul rulat
 +  * apelați funcția //free// pe o zonă de memorie nealocată sau pe una care a fost eliberată anterior
 +  * etc.
 +
 +Pentru a identifica problemele în cazul acesta puteți să folosiți [[http://​ocw.cs.pub.ro/​courses/​programare/​debugging?&#​other|printf stylel debugging]],​ cu mențiunea de [[http://​ocw.cs.pub.ro/​courses/​programare/​debugging?&#​pun_printf_dar_nu_apare_iar_apoi_crapa_programul|a fi atenți cum folosiți afișarea]].
 +
 +Pentru a identifica mai ușor punctul în care se întâmplă eroarea recomandăm folosirea [[https://​www.cs.cmu.edu/​~gilpin/​tutorial/​|gdb]] sau [[http://​valgrind.org/​docs/​manual/​QuickStart.html|valgrind]].
 +
 +Pentru ambele tool-uri vom avea nevoie să adăugăm la compilare flag-ul **-g** pentru a activa simbolurile de debugging. Astfel:
 +<​code>​
 +gcc -g -Wall ex1.c -o exe 
 +</​code>​
 +
 +Spre exemplu, o rulare simplă cu //​valgrind//​ ar arăta așa (dacă programul are argumente le adăugați în continuare):​
 +<​code>​
 +valgrind ./exe
 +</​code>​
 +
 +Urmăriți output-ul generat. Ar trebui să vă spună exact linia pe care se întâmplă eroarea și cauza acesteia. Mai multe detalii în tutoriale.
 +==== Pun printf dar nu apare, iar apoi crapă programul ====
 +
 +**printf** este o funcție care înainte de a afișa datele pe ecran le scrie într-un buffer intern pe care-l afișează pe ecran **doar în următoarele cazuri**:
 +  * se umple bufferul (este destul de mare!)
 +  * este forțată afișarea (folosind apelul: //​fflush(stdout);//​)
 +  * este afișat caracterul newline (adică //'​\n'//​)
 +
 +Dacă voi scrieți ceva în buffer (exemplu: //​printf("​Hello!"​);//​) iar după aceea apare o eroare de genul //​segmentation fault//, nu înseamnă că programul vostru nu a ajuns să execute instrucțiunea printf. Înseamnă doar că buffer-ul respectiv nu a ajuns să fie afișat pe ecran.
 +
 +<note warning>
 +Recomandăm să folosiți caracterul newline întotdeauna pentru debugging. Astfel:
 +<​code>​
 +printf("​Hello\n"​);​
 +</​code>​
 +</​note>​
 +
 +Ieșirea standard de eroare nu bufferează datele, ci le afișează imediat pe ecran. Puteți folosi acest flux, dacă doriți, astfel:
 +<​code>​
 +printf("​Hello"​);​
 +</​code>​
 +devine:
 +<​code>​
 +fprintf(stderr,​ "​Hello"​);​
 +</​code>​
 ==== Other ==== ==== Other ====
  
Line 49: Line 95:
  
 Recomandăm să începeți să afișați diversele valori esențiale de sus în jos. Cel mai probabil primul pas de verificat este imediat după citirea datelor de intrare. Asigurați-vă că ati citit valorile corect. Este o greșeală des întâlnită,​ mai ales printre începători,​ pentru că folosesc funcția //scanf// cu diverse formate fără să înțeleagă pe deplin ce se întâmplă. Recomandăm să începeți să afișați diversele valori esențiale de sus în jos. Cel mai probabil primul pas de verificat este imediat după citirea datelor de intrare. Asigurați-vă că ati citit valorile corect. Este o greșeală des întâlnită,​ mai ales printre începători,​ pentru că folosesc funcția //scanf// cu diverse formate fără să înțeleagă pe deplin ce se întâmplă.
 +
 +După ce ați verificat că ați citit corect datele, afișați valorile esențiale după fiecare secvență care le modifică în programul vostru. Nu puneți printf peste tot încă de la început, abordați incremental. Pentru bucle recomandăm să afișați indicele pentru fiecare iterație alături de alte valori pentru a putea urmări cum evoluează acestea.
programare/debugging.1477895679.txt.gz · Last modified: 2016/10/31 08:34 by laura.vasilescu
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