User Tools

Site Tools


bune-practici

Differences

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

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
Last revision Both sides next revision
bune-practici [2015/11/30 16:27]
catalin.vasile3004 [Segmentation Fault debugging: GDB quicky]
bune-practici [2015/11/30 17:00]
catalin.vasile3004 [Segmentation Fault debugging: GDB quicky]
Line 156: Line 156:
   - Într-o singură etapă se aduc mai multe instrucţiuni din memorie. Accesul la memorie este scump, şi dacă la fiecare instrucţiune de 5-6 bytes ne-am duce în memorie, nu am avea o performanţă foarte bună. Din acest motiv s-a inventat un modul în procesor, numit prefetching,​ în care se înmagazinează mai multe instrucţiuni de la adresa de la care se aduce cod/​instrucţiuni,​ pentru ca execuţia să fie mai fluidă.   - Într-o singură etapă se aduc mai multe instrucţiuni din memorie. Accesul la memorie este scump, şi dacă la fiecare instrucţiune de 5-6 bytes ne-am duce în memorie, nu am avea o performanţă foarte bună. Din acest motiv s-a inventat un modul în procesor, numit prefetching,​ în care se înmagazinează mai multe instrucţiuni de la adresa de la care se aduce cod/​instrucţiuni,​ pentru ca execuţia să fie mai fluidă.
   - În momentul în care procesorul îşi dă seama că una din instrucţiuni accesează o zonă nevalidă din memorie, trimite un semnal către sistemul de operare. Şi sistemul de operare este tot o bucată de cod care se execută pe procesor. Până când acest semnal trezeşte codul din sistemul de operare, e foarte posibil ca programul să mai fi executat o căruţă de instrucţiuni,​ din acest motiv, o înşiruire de printf-uri s-ar putea executa şi după instrucţiunea care a produs Segmentation Fault-ul.   - În momentul în care procesorul îşi dă seama că una din instrucţiuni accesează o zonă nevalidă din memorie, trimite un semnal către sistemul de operare. Şi sistemul de operare este tot o bucată de cod care se execută pe procesor. Până când acest semnal trezeşte codul din sistemul de operare, e foarte posibil ca programul să mai fi executat o căruţă de instrucţiuni,​ din acest motiv, o înşiruire de printf-uri s-ar putea executa şi după instrucţiunea care a produs Segmentation Fault-ul.
-  - Sistemul de operare se trezeşte şi închide forţat programul care a cauzat probleme. Printre datele primite de la semnal se regăseşte şi adresa instrucţiunii care a cauzat Segmentation Fault. Cu un debugger, se pot afla şi din userspace ce instrucţiune a cauzat Segmentation Fault.+  - Sistemul de operare se trezeşte şi închide forţat programul care a cauzat probleme. Printre datele primite de la semnal se regăseşte şi adresa instrucţiunii care a cauzat Segmentation Fault. Cu un debugger, se poate afla şi din userspace ce instrucţiune a cauzat Segmentation Fault.
 Exemplu de cod cu probleme: Exemplu de cod cu probleme:
 <file asm segfault.asm>​ <file asm segfault.asm>​
Line 221: Line 221:
 ./segfault param1 param2 param3 < fisier.in > fisier.out ./segfault param1 param2 param3 < fisier.in > fisier.out
 </​code>​ </​code>​
-''​set disassembly-flavor intel''​ vă ajută pentru a afişa eventualele printări de cod de asamblare într-o sintaxă cunoscută. Limbajul de asamblare reprezintă un set de alias-uri pentru instrucţiunile din binarul unui program. Aceste alias-uri nu au o formă standardizată motiv pentru care acestea diferă de la un asamblor la altul. By default, tool-urile din Linux folosesc sintaxa [[https://​en.wikibooks.org/​wiki/​X86_Assembly/​GAS_Syntax|AT&​T]]. 99% din tool-urile din Linux (gdb NU se află printre ele) pot primii argumentul ''​-M intel''​ pentru a afişa sau a trata codul de asamblare ca şi cum ar fi în sintaxa recomandată de Intel (care se regăseşte şi la NASM). Programe care pot primi acest flag sunt: gcc (gas), objdump, etc.+''​set disassembly-flavor intel''​ vă ajută pentru a afişa eventualele printări de cod de asamblare într-o sintaxă cunoscută. Limbajul de asamblare reprezintă un set de alias-uri pentru instrucţiunile din binarul unui program. Aceste alias-uri nu au o formă standardizată motiv pentru care acestea diferă de la un asamblor la altul. By default, tool-urile din Linux folosesc sintaxa [[https://​en.wikibooks.org/​wiki/​X86_Assembly/​GAS_Syntax|AT&​T]]. 99% din tool-urile din Linux (gdb NU se află printre ele) pot primii argumentul ''​-M intel''​ pentru a afişa sau a trata codul de asamblare ca şi cum ar fi în sintaxa recomandată de Intel (care se regăseşte şi la NASM). Programe care pot primi acest flag sunt: gcc (gas), objdump, etc.\\ 
 **Revenind la gdb**, în momentul în care rulăm o să ne dea următoarea eroare: **Revenind la gdb**, în momentul în care rulăm o să ne dea următoarea eroare:
 <code bash> <code bash>
Line 233: Line 233:
 0x08048423 in keep_printing () 0x08048423 in keep_printing ()
 </​code>​ </​code>​
-Pentru a vedea ce instrucţiunea a provocat segfault putem da următoarea comandă: +Pentru a vedea ce instrucţiunea a provocat segfaultputem da următoarea comandă: 
-<​code>​+<​code ​bash>
 (gdb) display/10i $pc (gdb) display/10i $pc
 1: x/10i $pc 1: x/10i $pc
Line 251: Line 251:
   * **display** face dump de la un pointer dat ca argument, în cazul nostru **$pc**   * **display** face dump de la un pointer dat ca argument, în cazul nostru **$pc**
   * **i**-ul îi spune lui **display** să interpreteze datele de acolo ca şi cum ar fi instrucţiuni   * **i**-ul îi spune lui **display** să interpreteze datele de acolo ca şi cum ar fi instrucţiuni
-  * **10** îi sune lui **display** câţi operanzi/​instrucţiuni ​de tipul **i** (instrucţiune) să afişeze\\ \\  +  * **10** îi spune lui **display** câţi operanzi de tipul **i** (instrucţiune) să afişeze\\ \\  
-Prin ''<​keep_printing+some_number>'',​ **gdb** incearcă să ne arate cam pe unde ar fi această instrucţiune. În cazul nostru instrucţiunea este aproape de label-ul **keep_printing**.+Prin ''<​keep_printing+some_number>'',​ **gdb** incearcă să ne arate cam pe unde ar fi această instrucţiune. În cazul nostru instrucţiunea este aproape de label-ul **keep_printing**.\\  
 +Pentru a vedea ce valoare a avut un registru la momentul în care s-a declanşat **segfault**-ul,​ puteţi da: 
 +<​code>​ 
 +(gdb) print $nume_registru 
 +</​code>​ 
 +În cazul nostru s-ar putea să ne intereseze ce valoare are **ecx**. Pentru a afla acest lucru: 
 +<​code>​ 
 +(gdb) print $ecx 
 +</​code>​ 
 ===== Categorie 3 ===== ===== Categorie 3 =====
  
   * TODO   * TODO
   * TODO   * TODO
bune-practici.txt · Last modified: 2015/11/30 21:08 by catalin.vasile3004