Zoeken op website

GNU Debugger of GDB: een krachtige broncode-foutopsporingstool voor Linux-programma's


Een debugger speelt een cruciale rol in elk softwareontwikkelingssysteem. Niemand kan in één keer een bugvrije code schrijven. In de loop van de ontwikkeling komen er bugs naar voren die moeten worden opgelost voor verdere verbetering. Een ontwikkelsysteem is niet compleet zonder een debugger. Gezien de gemeenschap van open source-ontwikkelaars is GNU Debugger hun beste keuze. Het wordt ook gebruikt voor commerciële softwareontwikkeling op platforms van het UNIX-type.

GNU Debugger, ook bekend als gdb, stelt ons in staat door de code te sluipen terwijl deze wordt uitgevoerd of door wat een programma probeerde te doen op het moment voordat het crashte. GDB helpt ons in principe om vier belangrijke dingen te doen om fouten in de broncode op te sporen.

  1. Start het programma en geef argumenten op die het algemene gedrag kunnen beïnvloeden.
  2. Stop het programma onder gespecificeerde omstandigheden.
  3. Onderzoek de crash of wanneer het programma werd gestopt.
  4. Verander de code en experimenteer onmiddellijk met de gewijzigde code.

We kunnen gdb gebruiken om zonder veel moeite programma's te debuggen die in C en C++ zijn geschreven. Vanaf nu is de ondersteuning voor andere programmeertalen zoals D, Modula-2 en Fortran gedeeltelijk.

Aan de slag met GNU Debugger of GDB

GDB wordt aangeroepen met de opdracht gdb. Bij het uitgeven van gdb wordt enige informatie over het platform weergegeven en wordt u naar de (gdb) prompt geleid, zoals hieronder weergegeven .

[root@fedora20 ~]# gdb
Voorbeelduitvoer
GNU gdb (GDB) Fedora 7.6.50.20130731-19.fc20 
Copyright (C) 2013 Free Software Foundation, Inc. 
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> 
This is free software: you are free to change and redistribute it. 
There is NO WARRANTY, to the extent permitted by law.  Type "show copying" 
and "show warranty" for details. 
This GDB was configured as "x86_64-redhat-linux-gnu". 
Type "show configuration" for configuration details. 
For bug reporting instructions, please see: 
<http://www.gnu.org/software/gdb/bugs/>. 
Find the GDB manual and other documentation resources online at: 
<http://www.gnu.org/software/gdb/documentation/>. 
For help, type "help". 
Type "apropos word" to search for commands related to "word". 
(gdb)

Typ help list om de verschillende soorten commando's te zien die beschikbaar zijn in gdb. Typ help gevolgd door een klassenaam voor een lijst met opdrachten in die klasse. Typ help all voor de lijst met alle opdrachten. Afkortingen van commandonamen zijn toegestaan als ze ondubbelzinnig zijn. U kunt bijvoorbeeld n typen in plaats van volgende of c voor doorgaan enzovoort.

Meest gebruikte GDB-opdrachten

Veelgebruikte gdb-opdrachten worden in de volgende tabel vermeld. Deze opdrachten moeten worden gebruikt vanaf de gdb-opdrachtprompt (gdb).

Command

Beschrijving

run

Start een programma-uitvoering

quit

Gdb afsluiten

print expr

Afdrukexpressie waarbij expr ook een variabelenaam kan zijn

next

Ga naar de volgende regel

step

Ga naar de volgende regel

continue

Ga verder vanaf de huidige regel tot het einde van het programma of het volgende breekpunt

Let op het verschil tussen de twee opdrachten stap en volgende. Het next commando gaat niet naar de functie als de volgende regel een functieaanroep is. Terwijl het stap commando naar de interne functie kan gaan en kijken wat daar gebeurt.

Een voorbeeldsessie met GDB

Beschouw de volgende broncode.


// sum.c
#include <stdio.h> 

int sum (int a, int b) { 
	int c; 
	c = a + b; 
	return c; 
} 

int main() { 
	int x, y, z; 
	printf("\nEnter the first number: "); 
	scanf("%d", &x); 
	printf("Enter the second number: "); 
	scanf("%d", &y); 
	z = sum (x, y); 
	printf("The sum is %d\n\n", z); 
	return 0; 
}

Om het uitvoerbestand te debuggen moeten we hetzelfde compileren met de -g optie naar gcc als volgt.

gcc -g sum.c -o sum

Het uitvoerbestand sum kan op een van de volgende twee manieren aan gdb worden gekoppeld:

1. Door het uitvoerbestand op te geven als argument voor gdb.

gdb sum

2. Voer het uitvoerbestand uit in gdb met de opdracht file.

gdb
(gdb) file sum

Met de opdracht list worden de regels in het broncodebestand weergegeven en wordt de aanwijzer verplaatst. Dus de eerste lijst geeft de eerste 10 regels weer en de volgende lijst geeft de volgende 10 weer, enzovoort.

(gdb) list
1	#include <stdio.h>   
2	 
3	int sum (int a, int b) { 
4		int c; 
5		c = a + b; 
6		return c; 
7	} 
8	 
9	int main() { 
10		int x, y, z;

Om de uitvoering te starten, geeft u de opdracht run op. Nu wordt het programma normaal uitgevoerd. Maar we zijn vergeten een aantal breekpunten in de broncode te plaatsen voor foutopsporing, toch? Deze breekpunten kunnen worden gespecificeerd voor functies of op gespecificeerde lijnen.

(gdb) b main

Opmerking: ik heb een afkorting b gebruikt voor break.

Nadat het breekpunt bij de hoofdfunctie is ingesteld, stopt het opnieuw uitvoeren van het programma bij regel 11. Hetzelfde kan in werking worden gesteld als het regelnummer eerder bekend is.

(gdb) b sum.c:11

Stap nu door de coderegels met behulp van de opdracht next of n. Het is belangrijk op te merken dat de opdracht next niet in de functiecode terechtkomt, tenzij er een breekpunt voor de functie is ingesteld. Laten we nu de opdracht print uitproberen. Stel het breekpunt in op de functiesom, zoals hieronder.

(gdb) b sum 
Breakpoint 1 at 0x4005aa: file sum.c, line 5. 
(gdb) r 
Starting program: /root/sum 

Enter the first number: 2 
Enter the second number: 3 

Breakpoint 1, sum (a=2, b=3) at sum.c:5 
5		c = a + b; 
(gdb) p a 
$1 = 2 
(gdb) p b 
$2 = 3
(gdb) c 
Continuing. 
The sum is 5 

[Inferior 1 (process 3444) exited normally]

Als het programma dat wordt uitgevoerd opdrachtregelparameters vereist, geef deze dan op samen met de opdracht run as.

(gdb) run   . . .

Gedeelde bibliotheekbestanden die aan het huidige actieve programma zijn gekoppeld, kunnen worden vermeld als.

(gdb) info share 
From                To                  Syms Read   Shared Object Library 
0x00000035a6000b10  0x00000035a6019c70  Yes         /lib64/ld-linux-x86-64.so.2 
0x00000035a641f560  0x00000035a6560bb4  Yes         /lib64/libc.so.6

Variabelen wijzigen

GDB kan ook variabelen wijzigen tijdens de uitvoering van het programma. Laten we dit eens proberen. Zoals hierboven vermeld, stelt u het breekpunt in op regel 16 en voert u het programma uit.

(gdb) r 
Starting program: /root/sum 

Enter the first number: 1 
Enter the second number: 2 

Breakpoint 1, main ( ) at sum.c:16 
16		printf("The sum is %d\n\n", z); 
(gdb) set z=4 
(gdb) c 
Continuing. 
The sum is 4

Nu a=1, b=2 en het resultaat moet z=3 zijn. Maar hier hebben we het eindresultaat gewijzigd in z=4 in de hoofdfunctie. Op deze manier kan het debuggen eenvoudiger worden gemaakt met behulp van gdb.

Breekpunten in-/uitschakelen

Voor een lijst met alle breekpunten typt u info breekpunten.

(gdb) info breakpoints 
Num     Type           Disp Enb Address            What 
1       breakpoint     keep y   0x00000000004005c2 in main at sum.c:11

Hier is er maar één breekpunt en dat is To. ingeschakeld schakel de breekpunten uit geef het breekpuntnummer op samen met de opdracht uitschakelen. Om achteraf in te schakelen gebruikt u de opdracht inschakelen.

(gdb) disable 1 
(gdb) info breakpoints 
Num     Type           Disp Enb Address            What 
1       breakpoint     keep n   0x00000000004005c2 in main at sum.c:11

U kunt de breekpunten ook verwijderen met de opdracht verwijderen.

Foutopsporing in lopende processen

Er draaien talloze processen op de achtergrond in een GNU/Linux-systeem. Om een lopend proces te debuggen moeten we eerst de proces-ID van dat specifieke proces vinden. pidof opdracht geeft u de pid van een proces.

pidof <process_name>

Nu moeten we deze pid aan gdb koppelen. Er zijn 2 manieren.

1. Door pid samen met gdb op te geven.

gdb -p <pid>

2. Gebruik de opdracht attach van gdb.

(gdb) attach <pid>

Dat is het voor nu. Dit zijn slechts de basisprincipes van gdb om een goede start te krijgen bij het debuggen van de broncode en het is veel meer dan de dingen die hierboven zijn uitgelegd. We kunnen bijvoorbeeld fouten opsporen met behulp van de stapelinformatie, omgevingsvariabelen en nog veel meer. Probeer eens met al deze dingen te spelen...