Forbedre kodekvaliteten og forhindre uventede resultater ved at lære, hvordan du bruger GNU Debugger til at afsløre uønskede fejl i din kode.
Debugging er en uundværlig færdighed for programmører og sikkerhedsforskere. At have en stærk forståelse af fejlretning giver dig mulighed for at forstå en eksekverbar på et lavere niveau og fange eventuelle lurende fejl.
GNU-debuggeren eller GDB er et tidløst fejlfindingsværktøj, som programmører har stolet på i årevis nu. Sådan bruger du GDB på Linux.
Forberedelse af prøveprogrammer
For at udforske funktionerne i GDB skal du bruge en eksekverbar fil til at eksperimentere med. Til demonstration vil du køre GDB på et nøglekontrolprogram én gang med kildekode og debug-symboler tilgængelige, én gang uden kildekode, og på et simpelt flertrådet program, der udskriver beskeder til skærmen, både skrevet i C og kompileret med GCC (GNU C kompilator).
Du kan brug enhver anden C-compiler men sørg for ikke at fjerne det binære.
Du vil højst sandsynligt køre GDB på dine egne programmer. Så sørg for at kompilere dem med
-g flag med gcc for at aktivere fejlfindingssymboler.Uden debug-symbolerne til stede og med en stærkt strippet binær, bliver du nødt til at debugge adskillelsen af programmet. Dette vil kræve, at du har et stærkt greb om samlesprog og hvordan hukommelsesallokering fungerer på Linux at forstå dataene i stakken og registrene.
Kørsel af et program i GDB
Du kører et program i GDB på et par måder. Enten skriv ind gdb , og når den er indlæst, skriv løb. Eller start gdb og brug derefter fil kommando, indlæs binæren i gdb, og kør den derefter med løb kommando.
Hvis dit program kræver kommandolinjeargumenter for at fungere korrekt, skal du sørge for at tilføje argumenterne efter programnavnet. Her er syntaksen til at indlæse programmet på GDB og udføre det med argumenter:
gdb
run
Eller:
gdb
file
run
Indstilling af brudpunkter med GDB
Breakpoints i debugging er manuelt indstillede hårde stop i kode, der stopper strømmen af eksekvering, når programmet når et breakpoint. Indstilling af breakpoints giver dig mulighed for at gå gennem koden og inspicere, hvordan hvert trin i eksekveringen påvirker data og variabler.
I GDB, når du fejlfinder et program med fejlfindingssymboler, kan du enten indstille et brudpunkt med navnet på funktionen eller indstille et brudpunkt baseret på linjenummeret. Her er syntaksen:
break main
break 47
For at se alle brudpunkter i den aktuelle fejlfindingssession skal du skrive:
info breakpoints
For at slette et bestemt brudpunkt eller flere brudpunkter skal du skrive:
delete 2
delete 3-5
GDB giver dig også mulighed for at indstille betingede brudpunkter, hvilket betyder, at programmet kun stopper, hvis en bestemt betingelse er opfyldt under udførelsen. Det kan være ændringen i værdien af et variabelt eller mislykket funktionskald eller hvad du vil. Her er syntaksen til at indstille betingede brudpunkter:
break if n == 2
Hvis du ønsker at fortsætte afviklingen af programmet efter at have ramt et breakpoint, skal du indtaste Blive ved kommando:
continue
Gå gennem kode
At træde gennem koden er afgørende for at forstå, hvordan programmet håndterer dataene. Ved at træde gennem forskellige funktioner i dit program og undersøge datatilstanden, kan du få en bedre forståelse af, hvordan programmet implementerer den logik, du har skrevet i kode.
Det hjælper dig også med at opdage roden til nedbrud og studieprogramadfærd med kirurgisk præcision, da du er i stand til at træde gennem hver linje kode, som du ønsker. Du kan gå gennem koden på tre primære måder i GDB:
- trin: Denne kommando fortæller GDB at træde ind i næste linje i kildefilen. Dette giver dig mulighed for i det væsentlige at krydse længden af kildekoden linje for linje.
- Næste: Denne kommando udfører den næste linje med kildekode i den aktuelle funktion og stopper derefter. Næste behandler en funktion som en enkelt linje, så hvis du bruger næste før et funktionskald, vil den behandle den som en enkelt linje og træde over den, i modsætning til trin kommando.
- Afslut: Afslut-kommandoen udfører alle de resterende linjer inde i den aktuelle funktion og stopper derefter.
Undersøgelse af variabler
Når du går gennem koden, vil du gerne undersøge værdien af variabler for at se, hvordan programlogikken ændrer dem. Her er syntaksen til at se værdien af variabler i GDB:
print
Hvis du ønsker at udskrive ændringerne i værdien af en variabel, hver gang den opdateres, skal du bruge displaykommandoen. Dette er især nyttigt, når du vil spore og udskrive værdien af en variabel i en løkke:
display
Indstilling af vagtpunkter
Watchpoints og betingede breakpoints er tæt beslægtede, da de begge reagerer på ændringer i et program. Watchpoints bruges til at spore ændringer i data i koden. For eksempel vil du måske have, at programmet går i stykker, når værdien af en variabel ændres. Sådan gør du det med GDB:
watch
Trådspecifik debugging med GDB
GDB giver dig mulighed for at udføre trådspecifik debugging, når du arbejder med multitrådede programmer. Til demonstration vil vi arbejde med et simpelt C-program, der bruger fire tråde til at udskrive meddelelser med hver tråd.
For at se de aktuelle tråde i dit program, brug info kommando:
info threads
For at arbejde med en bestemt tråd kan du vælge den fra listen ved hjælp af dens indeksnummer. For eksempel:
thread 2
Når du har valgt tråden, kan du gå gennem dens udførelsesflow ved hjælp af trin, Næste, og Afslut kommandoer som vist ovenfor.
Fjernfejlfinding med GDB
Du kan også fjernfejlfinde programmer, der er placeret på et andet system. For at gøre det skal du konfigurere gdbserver på målmaskinen. Du kan nemt installere det ved at bruge standardpakkehåndteringen for din distribution eller andre pakkeadministratorer, du har installeret på dit system.
For eksempel, for at installere gdbserver på dine Ubuntu- eller Debian-baserede systemer, skal du bruge APT:
sudo apt install gdbserver
Når det er installeret, skal du flytte ind i mappen med binæren og køre denne kommando for at starte gdbserver:
gdbserver :
gdbserver skal returnere det output, som den er oppe og lytter til på den port, du har defineret. Start nu GDB på klientmaskinen og opret forbindelse til fjernserveren ved hjælp af mål kommando:
target remote :
Skrivning af GDB-scripts for at automatisere fejlfinding
GDB tillader programmører at skrive GDB-scripts, der udfører GDB-kommandoer automatisk. Dette hjælper enormt, når du forsøger at debugge den samme del af en kode flere gange. I stedet for at skulle indstille brudpunktet, træde gennem kode og udskrive variabelværdier hver gang du indlæser binæren, kan du bruge et GDB-script til at automatisere hele processen.
Her er et eksempel:
set logging enabled on
set logging file sample.out
break main
command 1
backtrace
print N
continue
end
quit
I scriptet ovenfor beder du GDB om at aktivere logning og gemme loggen i en fil kaldet sample.out, og indstil derefter et brudpunkt ved vigtigste fungere.
For brudpunkt nummer 1, i dette tilfælde, brudpunktet ved funktion hoved, skal du køre følgende kommandoer: tilbagesporing, Print, Blive ved. Grundlæggende vil GDB først køre en backtrace, derefter udskrive værdien af variablen "N", fortsætte udførelse og til sidst afslutte.
For at udføre dette script, brug:
gdb -x