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.
- Start het programma en geef argumenten op die het algemene gedrag kunnen beïnvloeden.
- Stop het programma onder gespecificeerde omstandigheden.
- Onderzoek de crash of wanneer het programma werd gestopt.
- 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...