>> DOUG LLOYD: Okej GDB.
Vad är det exakt?
Så GDB, som står för GNU Debugger,
är en riktigt fantastisk verktyg som vi kan använda för att hjälpa oss att felsöka våra program,
eller ta reda på var saker och ting är går fel i våra program.
GDB är otroligt kraftfullt, men utgången och interaktion med det
kan vara lite kryptiskt.
Det är oftast ett kommandoradsverktyg, och det kan kasta en hel del meddelanden på dig.
Och det kan typ av svårt att tolka exakt vad som händer.
Lyckligtvis har vi vidtagit åtgärder att åtgärda problemet för dig
när du arbetar genom CS50.
Om du inte använder den grafiska debugger, som min kollega Dan
Armandarse har talat ganska lite om i en video som
bör vara över här just nu, kan du behöva
att använda dessa kommandorad verktyg för att arbeta med GDB.
Om du arbetar i CS50 IDE, behöver du inte göra detta.
Men om du inte arbetar i CS50 IDE,
kanske med hjälp av en version av CS50 Appliance,
eller annan Linux Systemet med GDB installerat på det,
Du kan behöva använda Dessa kommandoraden.
>> Och eftersom du kanske måste göra det, det är
användbar bara för att förstå hur GDB arbetar från kommandoraden.
Men återigen, om du är använder CS50 IDE, du
kan använda den grafiska debugger som är inbyggd i IDE.
Så för att få saker och ting med GDB, att starta felsökning
processen av en viss program, behöver du göra
är typ GDB följt av programmets namn.
Så till exempel, om ditt program är Hej, skulle du skriver GDB hej.
>> När du gör det, du kommer att dra upp GDB miljön.
Ditt snabba kommer att förändras, och istället för att vara vad den vanligtvis
är när du skriver saker vid kommandot line-- ls,
cd-- alla dina typiska Linux kommandon, ditt snabba
kommer att ändras till, förmodligen, något liknande parentes GDB parenteser.
Det är din nya GDB snabb, eftersom du är inne i GDB miljön.
Väl inne i denna miljö, det finns två stora kommandon
att du antagligen kommer att använda i följande ordning.
>> Den första är b, som är en förkortning för paus.
Och när du skriver b, du vanligtvis Skriv namnet på en funktion,
eller om du råkar veta kring vad radnummer
ditt program börjar att bete sig lite konstigt,
Du kan skriva en linje nummer där också.
Vilken b, eller paus, gör är det tillåter ditt program
att köra fram till en viss punkt, nämligen, namnet på funktionen
som du anger eller linjen nummer som du anger.
>> Och på den punkten, det fryser utförande.
Detta är en riktigt bra sak, eftersom när avrättning har varit fryst,
du kan börja mycket långsamt stega igenom ditt program.
Vanligtvis om du har varit igång dina program, de är ganska kort.
Vanligtvis skriver du punkt snedstreck allt namnet på programmet, tryck Enter,
och innan du kan blinka, din Programmet är redan klar.
Det är inte verkligen en hel del tid att försöka och räkna ut vad som går fel.
Så det verkligen att kunna bromsa saker ner genom att sätta en brytpunkt med b,
och sedan kliva in.
>> Sen när du har ställt in paus Nu kan du köra programmet.
Och om du har någon kommandoradsargumenten,
du anger dem här, inte när du skriver GDB ditt programnamnet.
Du anger alla kommandoraden argument genom att ta r eller springa,
och sedan vad kommandoradsargumenten du behöver inne i ditt program.
Det finns ett antal andra riktigt viktiga och användbara kommandon
insidan av BNP miljön.
Så låt mig bara snabbt gå igenom några av dem.
>> Den första är N, som är en förkortning för nästa, och du kan skriva nästa istället för n,
båda skulle fungera.
Och det är bara stenografi.
Och som du har förmodligen redan fått används till att kunna skriva saker
kortare är generellt bättre.
Och vad det kommer att göra är det kommer kliva fram ett kodblock.
Så det kommer att gå framåt tills ett funktionsanrop.
Och sedan i stället för dykning i denna funktion
och gå igenom allt detta funktioner kod, kommer det bara funktionen.
>> Funktionen kommer att kallas.
Det kommer att göra allt sitt arbete är.
Det kommer att returnera ett värde till funktionen som kallade det.
Och då kommer du gå vidare till nästa rad i nämnda anropsfunktionen.
Om du vill kliva insidan av funktionen,
i stället för att bara ha det utför, särskilt
om du tror att problemet kan ligga inne i denna funktion,
Du kan naturligtvis sätta en paus punkt inuti av den funktionen.
Eller om du redan kör, kan du Använd s att kliva fram en rad kod.
>> Så det här kommer att gå in och dyka i funktioner,
istället för att bara ha execute och fortsätter i funktion
att du är i för felsökning.
Om du någonsin vill veta värdet på en variabel,
Du kan skriva p, eller ut, och sedan variabelnamnet.
Och det kommer att skriva ut till dig, insidan av GDB miljön,
namnet på den variabel, som du-- ursäkta mig-- värdet av variabeln
att du har namngett.
Om du vill veta värdet av varje lokal variabel tillgänglig från där
du befinner dig i ditt program, kan du skriva info lokalbefolkningen.
Det är mycket snabbare än skriver p och sedan vad som helst,
notering ut alla variabler som du vet existerar.
Du kan skriva info lokalbefolkningen, och det kommer att skriva ut allt för dig.
Nästa är upp bt, som är kort för Back Trace.
Nu, i allmänhet, speciellt i början av CS50,
du kommer inte riktigt att få tillfälle att använda bt eller Back Trace,
eftersom du inte ska ha funktioner att ringa till andra funktioner.
>> Du kanske har huvud kallar en funktion, men det är förmodligen det.
Du behöver inte ha den andra funktion ringer en annan funktion, som
anropar en annan funktion, och så vidare.
Men som dina program får mer komplex, och i synnerhet
när du börjar arbeta med rekursion, rygg spår
kan vara ett riktigt bra sätt att låta dig typ av få något sammanhang för var
Jag är i mitt program.
Så säger du har skrivit din kod, och du vet att huvud anropar en funktion
f, vilket kräver en funktion g, vilket kräver en funktion h.
Så vi har flera skikt av häckande pågår här.
>> Om du är inne i din GDB miljö,
och du vet att din insida av h, men du glömmer
vad fick dig dit du är-- du kan skriva bt, eller tillbaka spår,
och det kommer att skriva ut h, g, f main, tillsammans med några andra uppgifter, som
ger dig en aning om att, OK huvud kallas f, f kallas g, g kallas h,
och det är där jag för närvarande är i mitt program.
Så det kan vara riktigt bra, särskilt som det kryptiska ness GDB
blir lite överväldigande, till ta reda på exakt var saker är.
Slutligen, när programmet är klar, eller när du är klar felsökning det
och du vill steg bort från GDB miljön,
hjälper det att veta hur man får ut av det.
Du kan skriva q, eller avsluta, att komma ut.
Nu, innan dagens video Jag förberedde en buggig program
kallas buggy1, som jag sammanställt från en fil som kallas buggy1.c.
Som man kan förvänta sig, detta Programmet är i själva verket paraplyvagn.
Något går fel när jag försöker och kör den.
Nu, tyvärr, jag av misstag bort min buggy1.c fil,
så för mig att räkna ut vad som händer fel med det här programmet,
Jag kommer att behöva använda GDB typ av blint, försöker
att navigera genom detta program för att räkna ut exakt vad som går fel.
Men med bara de verktyg Vi har redan lärt oss om,
Vi kan ganska mycket siffra reda på exakt vad det är.
Så låt oss gå över till CS50 IDE och ta en titt.
OK, så vi är här i min CS50 IDE miljö,
och jag ska zooma in en liten bit så att du kan se en lite mer.
I mitt terminalfönster, om jag lista innehållet i min nuvarande chef
med ls, vi får se att jag har ett par källfiler
här, inklusive tidigare diskuterats buggy1.
Vad exakt som händer när Jag försöker köra buggy1.
Nåväl låt oss ta reda på.
Jag skriver dot slash, buggy, och jag slog Enter.
>> Segmente fel.
Det är inte bra.
Om ni minns, en segmentering fel typiskt
uppstår när vi tillgång till minne att vi inte är tillåtet att röra.
Vi har på något sätt kommit utanför gränserna
av vad programmet, den kompilator, har gett oss.
Och så redan det är en ledtråd för att hålla i verktygslådan
när vi börjar felsökningsprocessen.
Något har gått lite fel här.
>> Okej, så låt oss börja upp GDB miljön
och se om vi kan lista ut exakt vad problemet är.
Jag kommer att rensa skärmen, och jag kommer att skriva GDB
igen, att komma in i GDB miljön, och namnet på programmet
att jag vill felsöka, buggy1.
Vi får ett litet meddelande, läsning symboler från buggy1, gjort.
Allt detta betyder är det drog tillsammans all kod,
och nu är det laddats in GDB, och det är redo att gå.
>> Nu, vad jag vill göra?
Minns du vad första steg typiskt är
efter att jag är inne i denna miljö?
Förhoppningsvis, sade du ställer en brytpunkt, eftersom
i själva verket det är vad jag vill göra.
Nu behöver jag inte har källkoden för detta
framför mig, som är förmodligen inte den typiska användningsfall, förresten.
Du kommer förmodligen.
Så det är bra.
Men förutsatt att du inte, vad är den funktion som du vet
finns i varenda C-programmet?
Oavsett hur stor eller hur komplicerat Det är, finns denna funktion definitivt.
Main, eller hur?
>> Så inte allt, vi kan ange en brytpunkt vid huvud.
Och återigen, jag kunde bara skriva break, i stället för miljarder.
Och om du är nyfiken, om du någonsin skriva ut en lång kommando
och sedan inser att du skrev fel sak,
och du vill bli av allt som jag gjorde precis,
du kan ta kontroll U, som kommer radera allt och ta dig tillbaka
till början av markörlinjer.
Mycket snabbare än bara hålla ner ta bort eller slå det ett gäng gånger
över.
>> Så vi ska sätta en brytpunkt vid huvud.
Och som ni kan se, säger vi har ange en brytpunkt vid fil buggy1.c,
och uppenbarligen den första raden kod för huvud ligger i linje sju.
Återigen, vi har inte källfilen här,
men jag kommer att anta att det är berättade sanningen.
Och sedan, jag försöker bara och kör programmet, r.
Startprogrammet.
Okej, så det här meddelandet är lite kryptiskt.
Men i grund och botten vad händer här är att det är bara
säger att jag har nått min paus punkt, brytpunktsnummer 1.
>> Och sedan att kodrad, ingen sådan fil eller katalog.
Enda anledningen till att Jag ser detta meddelande
är att jag av misstag bort min buggy.c fil.
Om mitt buggy1.c fil existerade i den aktuella katalogen,
den linjen rätt det skulle faktiskt berätta vad kodraden
rally läser.
Tyvärr, jag tog bort det.
Vi kommer att behöva slags navigera genom detta lite mer blint.
>> OK, så låt oss se, vad vill jag göra här?
Tja, skulle jag vilja veta vad lokal variabler kanske är tillgängliga för mig.
Jag har börjat mitt program.
Låt oss se vad som kan vara redan initierats för oss.
Jag skriver Infolokalbefolkningen, ingen lokalbefolkningen.
Okej, så att inte ge mig massor av information.
Jag kunde försöka skriva ut en variabel, men jag vet inte något variabelnamn.
Jag kunde prova en back spår, men jag är inne i huvud,
så jag vet att jag har inte gjort en annan funktion samtal just nu.
>> Så ser ut som min enda alternativ är att använda n eller så och börja dyka.
Jag kommer att använda n.
Så jag skriver n.
Oh my gosh, vad som händer här.
Program mottagna signaler, SIGSEGV segmentering fel,
och sedan en massa grejer.
Jag är redan överväldigad.
Tja, det finns faktiskt en mycket att lära här.
Vad säger detta oss?
Vad det säger oss är detta program är om, men har ännu inte, seg fel.
Och framför allt, jag kommer för att zooma in ännu längre här,
det handlar om att seg fel om något som kallas strcmp.
>> Nu kanske vi inte har diskuterat denna funktion utförligt.
Men det är-- eftersom vi inte tänker att prata om varje funktion som
existerar i C-standard library-- men de är alla tillgängliga för dig,
särskilt om du tar en titta på reference.cs50.net.
Och strcmp är en riktigt kraftfull funktion som finns inuti
av string.h sidhuvud fil, som är en rubrik
fil som är tillägnad funktioner som arbetar med och manipulera strängar.
>> Och framför allt, vad strcmp gör är jämförs värdena för två strängar.
Så jag är på väg att segmentering fel på ett samtal till strcmp det verkar.
Jag slog n, och faktum är att jag får meddelandet, Programmet avslutas med signal SIGSEGV
segmentering fel. Så nu Jag har faktiskt seg klandras,
och mitt program har ganska mycket effektivt gett upp.
Detta är slutet av programmet.
Det gick sönder, kraschade den.
Så var inte mycket, men jag faktiskt lärde en hel del
från denna lilla erfarenhet.
Vad har jag lärt mig?
Tja, kraschar mitt program ganska mycket omedelbart.
Mitt program kraschar på ett samtal till strcmp, men jag
inte har några lokala variabler i mitt program vid den tidpunkt då den kraschar.
Så vad sträng eller strängar, skulle jag kunna vara att jämföra.
Om jag inte har någon lokal variabler, kanske du
förmoda att jag have-- det kanske är en global variabel, som kan vara sant.
>> Men generellt verkar det som jag jämföra
till något som inte existerar.
Så låt oss undersöka att lite längre.
Så jag kommer att rensa skärmen.
Jag ska sluta ut ur GDB miljö för en sekund.
Och jag tänker, OK, så det finns inga lokala variabler i mitt program.
Jag undrar om kanske jag ska passera i en sträng som en kommandorad argument.
Så låt oss bara testa detta.
Jag har inte gjort det här förut.
>> Låt oss se om kanske om jag kör det här programmet med en kommandorad argument det fungerar.
Huh, ingen segmentering fel där.
Det sa bara till mig att jag räknat ut.
Så kanske det är fix här.
Och faktiskt, om jag går tillbaka och titta på själva källkoden för buggy1.c,
verkar det som om det jag gör är Jag gör ett anrop till strcmp utan
kontrollera om i själva verket argv [1] föreligger.
Detta är faktiskt den källkoden för buggy1.c.
Så vad jag verkligen behöver göra här för att fixa mitt program,
förutsatt att jag har fil framför mig, är
att bara lägga till en kontroll att göra till att argc är lika med två.
Så det här exemplet, igen, som jag sa, är lite krystat, eller hur?
Du vanligtvis inte kommer att av misstag tar bort din källkod
och sedan måste försöka och felsöka programmet.
Men förhoppningsvis gav det du en illustration
av den typen av saker som du kan tänka på
som du felsökt programmet.
>> Vad är läget här?
Vilka variabler gör jag har tillgång till mig?
Var exakt är mitt program kraschar, på vilken linje,
på vilken anrop till vilken funktion?
Vilken typ av ledtrådar ger detta mig?
Och det är precis det typ av tänkesätt som du
bör få i när du är funderar på att felsöka dina program.
>> Jag är Doug Lloyd.
Detta är CS50.