DOUG LLOYD: Greit GDB. Hva er det egentlig? Så GDB, som står for GNU Debugger, er en virkelig fantastisk verktøy som vi kan bruke til å hjelpe oss feilsøke våre programmer, eller finne ut hvor ting er går galt i våre programmer. GDB er utrolig kraftig, men utgang og vekselvirkning med den kan være litt kryptisk. Det er vanligvis et kommandolinjeverktøy, og det kan kaste en masse meldinger på deg. Og det kan slags vanskelig å analysere nøyaktig hva som skjer. Heldigvis har vi tatt skritt å løse dette problemet for deg mens du arbeider gjennom CS50. Hvis du ikke bruker det grafiske debugger, som min kollega Dan Armandarse har snakket ganske litt om i en video som bør være over her akkurat nå, må du kanskje å bruke disse kommandolinje verktøy å jobbe med GDB. Hvis du jobber i CS50 IDE, trenger du ikke å gjøre dette. Men hvis du ikke er arbeider i CS50 IDE, kanskje bruker en versjon av CS50 Appliance, eller en annen Linux operativsystem system med GDB installert på den, du må kanskje bruke disse kommandolinjeverktøy. Og siden du kanskje må gjøre det, det er nyttig bare å forstå hvordan GDB arbeider fra kommandolinjen. Men igjen, hvis du er bruke CS50 IDE, du kan bruke det grafiske debugger som er bygd inn i IDE. Så for å få ting i gang med GDB, for å starte feilsøking Prosessen med en spesiell program, trenger alt du gjør er å skrive GDB fulgt av programnavnet. Så for eksempel hvis programmet er hei, ville du skriver GDB hei. Når du gjør det, du kommer å trekke opp GDB miljøet. Ditt spørsmål ville endre, og stedet for å være hva det vanligvis er når du skriver ting Ved lede line-- ls, cd-- alle dine typiske Linux-kommandoer, spør din vil endre til, sannsynligvis, noe som parentes GDB parentes. Det er din nye GDB teksten, fordi du er inne på GDB miljø. Når du er inne i et slikt miljø, det er to viktige kommandoer at du vil sannsynligvis bruke i følgende rekkefølge. Den første er b, der er en forkortelse for pause. Og når du skriver b, du vanligvis Skriv inn navnet på en funksjon, eller hvis du tilfeldigvis vite rundt hva linjenummer programmet starter å oppføre seg litt rart, du kan skrive en linje nummeret der også. Hva b, eller pause, gjør er det tillater programmet å kjøre frem til et visst punkt, nemlig navnet på funksjonen som du angir eller linjen nummeret du spesifiserer. Og på det punktet, det vil fryse utførelse. Dette er en veldig god ting, fordi når henrettelsen har vært frosset, du kan begynne å veldig sakte gå gjennom programmet. Vanligvis, hvis du har vært i gang programmene dine, de er ganske kort. Vanligvis skriver du dot slash uansett navnet på programmet, trykk Enter, og før du kan blinke, din Programmet er allerede ferdig. Det er egentlig ikke mye tid til å prøve og finne ut hva som går galt. Så det egentlig å være i stand til å bremse ting ned ved å sette en pause poeng med b, og deretter stepping. Så når du har satt inn pause punktet, kan du kjøre programmet. Og hvis du har noen kommandolinjeargumenter, du angir dem her, ikke når du skriver GDB programmet navn. Du angir alle kommandolinjen argumenter ved å ta r, eller løpe, og deretter hva kommandolinjeargumentene du trenger inne i programmet. Det er en rekke andre virkelig viktige og nyttige kommandoer Innsiden av BNP miljø. Så la meg bare raskt gå over noen av dem. Den første er n, som er en forkortelse for neste, og du kan skrive neste stedet for n, begge ville fungere. Og det er bare stenografi. Og som du sikkert har allerede fått vant til, å være i stand til å skrive ting kortere er generelt bedre. Og hva det vil gjøre det vil gå frem en blokk med kode. Så det vil gå videre til en funksjon. Og så i stedet for dykke inn i den funksjonen og gå gjennom alle som fungerer kode, vil det bare ha funksjonen. Funksjonen vil bli kalt. Det vil gjøre alt arbeidet er. Den vil vende tilbake til en verdi den funksjon som kalte den inn. Og da vil du gå videre til neste linje som ringer funksjonen. Hvis du ønsker å gå Innsiden av funksjon, i stedet for bare å ha det utføre, spesielt hvis du tror at problemet kan ligge inne i den funksjonen, du kan selvfølgelig sette en pause peke på innsiden av den funksjonen. Eller hvis du allerede er i gang, kan du bruke s å gå frem en linje med kode. Så dette vil gå inn og dykke inn i funksjoner, i stedet for å bare ha henrette og fortsetter i funksjonen at du er i for debugging. Hvis du noen gang ønsker å vite verdien av en variabel, du kan skrive p, eller Print, og deretter variabelnavnet. Og som vil skrive ut til deg, innsiden av GDB miljø, navnet på den variable, som you-- unnskylde me-- verdien av variabelen at du har navngitt. Hvis du ønsker å vite verdiene av hvert lokal variabel tilgjengelig fra hvor du er nå i program, kan du skrive info lokalbefolkningen. Det er mye raskere enn skrive p og deretter hva, liste ut alle variabler som du vet finnes. Du kan skrive inn info lokalbefolkningen, og det vil skrive ut alt for deg. Neste opp er bt, som er kort for Back Trace. Nå, generelt, spesielt tidlig i CS50, du vil egentlig ikke ha anledning å bruke bt, eller Back Trace, fordi du ikke har det funksjoner som kaller andre funksjoner. Du har kanskje viktigste samtale en funksjon, men det er sannsynligvis det. Du har ikke den andre funksjonen ringer en annen funksjon, hvilken kaller en annen funksjon, og så videre. Men som programmene dine få mer kompleks, og særlig når du begynner å arbeide med rekursjon, tilbake spor kan være en veldig nyttig måte å fortelle deg slags få noen sammenheng for hvor Jeg er i mitt program. Så sier du har skrevet koden, og du vet at hoved kaller en funksjon f, som kaller en funksjon g, noe som krever en funksjon h. Så vi har flere lag av hekkende skjer her. Hvis du er inne i din GDB miljø, og du vet inni av h, men du glemmer om det som fikk deg til hvor du are-- du kan skrive bt, eller tilbake spor, og det vil skrive ut h, g, f viktigste, sammen med annen informasjon, som gir deg en anelse om at, OK hoved kalt f, f kalt g, g kalt h, og det er der jeg for tiden er i mitt program. Så det kan være veldig nyttig, særlig ettersom det kryptiske-ness of GDB blir litt overveldende, til finne ut nøyaktig hvor ting er. Til slutt, når programmet er ferdig, eller når du er ferdig feilsøkt og du ønsker å gå bort fra GDB miljø, det hjelper å vite hvordan man skal komme seg ut av det. Du kan skrive q, eller Avslutt for å komme seg ut. Nå, før dagens video Jeg utarbeidet en buggy program kalt buggy1, som jeg kompilert fra en fil kalt buggy1.c. Som du kanskje forventer, dette Programmet er faktisk buggy. Noe går galt når jeg prøver og kjøre den. Nå, dessverre, jeg uforvarende slettet min buggy1.c fil, så i orden for meg å finne ut hva som går galt med dette programmet, Jeg er nødt til å bruke GDB slags blindt, prøver å navigere gjennom dette programmet til finne ut nøyaktig hva som går galt. Men ved hjelp av bare de verktøyene vi allerede har lært om, Vi kan ganske mye tall ut nøyaktig hva det er. Så la oss gå over til CS50 IDE og ta en titt. OK, så vi er her i min CS50 IDE miljø, og jeg skal zoome inn litt slik at du kan se litt mer. I min terminal-vinduet, hvis jeg liste innholdet i min nåværende direktør med ls, vil vi se at jeg har et par kildefiler her, inkludert tidligere diskutert buggy1. Hva skjer når Jeg prøver og kjøre buggy1. Vel la oss finne det ut. Jeg skriver dot slash, buggy, og jeg trykker på Enter. Segmentering feil. Det er ikke bra. Hvis du husker, en segmentering feil typisk oppstår når vi tilgang til minnet at vi ikke har lov til å røre. Vi har liksom nådd utenfor grensene av det programmet, kompilator, har gitt oss. Og så allerede at det er en holdepunkt for å holde i verktøykassen som vi begynner feilsøking prosessen. Noe har gått litt galt her. Greit, så la oss starte opp GDB miljø og se om vi kan finne ut hva problemet er. Jeg kommer til å tømme skjermen min, og jeg kommer til å skrive GDB igjen, for å gå inn i GDB miljø, og navnet på programmet som jeg ønsker å feilsøke, buggy1. Vi får en liten melding, lesing symboler fra buggy1, gjort. Alt det betyr er det trukket sammen hele koden, og nå er det blitt lastet inn GDB, og den er klar til å gå. Nå, hva jeg ønsker å gjøre? Husker du hva den Første skritt er typisk etter at jeg er inne i dette miljøet? Forhåpentligvis, sa du stille en pause punkt, fordi faktisk det er det jeg ønsker å gjøre. Nå, jeg har ikke det kildekoden for dette foran meg, som sannsynligvis ikke den typiske brukstilfellet, for øvrig. Du vil sannsynligvis. Så det er bra. Men forutsatt at du ikke gjør det, hva er den ene funksjonen som du vet eksisterer i hver enkelt C-program? Uansett hvor stort eller hvor komplisert det er, eksisterer denne funksjonen absolutt. Main, ikke sant? Så sviktende alt annet, kan vi satt en pause poeng på hoved. Og igjen, jeg kunne bare skrive bryte viktigste, i stedet for b. Og hvis du er nysgjerrig, hvis du stadig skriver ut en lang kommando og deretter innse at du skrev feil ting, og du ønsker å bli kvitt av alt som jeg nettopp gjorde, du kan ta kontroll U, som vil slette alt og bringe deg tilbake til begynnelsen av markørlinjer. Mye raskere enn bare hold nede slette eller treffer det en haug ganger over. Så vi får satt en pause poeng på hoved. Og som du kan se, sier det vi har satt en pause punkt på filen buggy1.c, og tilsynelatende den første linjen kode for hoved er linje sju. Igjen, har vi ikke kildefilen her, men jeg vil anta at det er fortelle meg sannheten. Og så, jeg prøver bare og kjøre programmet, r. Starte programmet. Greit, så denne meldingen er litt kryptisk. Men i utgangspunktet hva som er skjer her er det bare forteller meg at jeg har truffet min pause punkt, break punkt nummer en. Og da, at kodelinje, ingen slik fil eller katalog. Den eneste grunnen til at Jeg ser at meldingen er fordi jeg uforvarende slettet min buggy.c fil. Hvis min buggy1.c fil eksisterte i gjeldende katalog, den linjen der ville faktisk fortell meg hva linje med kode bokstavelig leser. Dessverre, slettet jeg det. Vi er nødt til å slags navigere gjennom denne litt mer blindt. OK, så la oss se, hva ønsker jeg å gjøre her? Vel, jeg vil gjerne vite hva lokal variabler kanskje er tilgjengelige for meg. Jeg har begynt mitt program. La oss se hva som kan være allerede initialisert for oss. Jeg skriver Info lokalbefolkningen, ingen lokalbefolkningen. All right, slik at ikke gi meg massevis av informasjon. Jeg kan prøve og skrive ut en variabel, men jeg vet ikke noen variabelnavn. Jeg kunne prøve en tilbake spor, men jeg er inne i hoved, så jeg vet jeg ikke har gjort en annen funksjon samtale akkurat nå. Så ser ut som min eneste alternativene er å bruke n eller så, og begynner å dykke i. Jeg kommer til å bruke n. Så jeg skriver n. Oh my gosh, hva som skjer her. Programmet fikk signaler, SIGFPE segmentering feil, og deretter en hel haug med ting. Jeg er allerede overveldet. Vel, det er faktisk en mye å lære her. Så hva forteller dette oss? Hva det forteller oss er at dette programmet er i ferd med å, men har ikke ennå, SEG feil. Og spesielt, jeg kommer for å zoome inn enda mer her, det handler om å SEG feil om noe som kalles strcmp. Nå kan vi ikke har diskutert denne funksjonen mye. Men det er-- fordi vi ikke kommer å snakke om hver funksjon som finnes i den C-standarden library-- men de er alle tilgjengelige for deg, spesielt hvis du tar en se på reference.cs50.net. Og strcmp er en virkelig kraftig funksjon som eksisterer inne av string.h header fil, som er en header fil som er dedikert til funksjoner at arbeidet med og manipulere strenger. Og spesielt hva strcmp gjør er Det sammenligner verdiene av to strenger. Så jeg er i ferd med å segmentering feil på et kall til strcmp det virker. Jeg traff n, og faktisk får jeg meldingen, Programmet avsluttes med signal SIGFPE segmentering feil. Så nå Jeg har faktisk SEG ugyldig, og mitt program har ganske mye effektivt gitt opp. Dette er slutten av programmet. Det brøt sammen, det krasjet. Så var ikke mye, men jeg faktisk gjorde lære ganske mye fra denne lille opplevelsen. Hva har jeg lært? Vel, krasjer programmet mitt ganske mye umiddelbart. Mitt program krasjer på Et kall til strcmp, men jeg har ingen lokale variabler i mitt program på den tiden at det krasjer. Så hva streng eller strenger, kunne jeg muligens være å sammenligne. Hvis jeg ikke har noen lokal variabler, kanskje du anta at jeg have-- det kanskje er en global variabel, noe som kan være sant. Men generelt ser det ut til som jeg sammenlikne til noe som ikke eksisterer. Så la oss undersøke at litt lenger. Så jeg kommer til å tømme skjermen min. Jeg kommer til å slutte seg ut av GDB miljø for et sekund. Og jeg tenker, OK, så det er ingen lokale variabler i mitt program. Jeg lurer på om kanskje jeg skal passere i en streng som en kommandolinje argument. Så la oss bare teste ut dette. Jeg har ikke gjort dette før. La oss se om kanskje hvis jeg kjører dette programmet med en kommandolinje argument fungerer det. He, nei segmentering feil der. Det fortalte meg at jeg fant det ut. Så kanskje det er fix her. Og faktisk, hvis jeg går tilbake og ser på selve kildekoden for buggy1.c, det virker som om det jeg gjør er Jeg gjør et kall til strcmp uten å sjekke om faktisk argv [1] eksisterer. Dette er faktisk kildekoden for buggy1.c. Så det jeg trenger virkelig å gjøre her for å fikse mitt program, forutsatt at jeg har fil foran meg, er å bare legge en sjekk for å gjøre sikker på at argc er lik 2. Så dette eksempelet, igjen, som jeg sa, er litt contrived, ikke sant? Du vanligvis ikke kommer til å uhell sletter kildekoden og deretter må prøve og feilsøke programmet. Men forhåpentligvis, det ga du en illustrasjon av den slags ting som du kan tenke på som du feilsøke programmet. Hva er tingenes tilstand her? Hva variabler gjør jeg har tilgjengelig for meg? Hvor nøyaktig er mitt program krasje, på hvilken linje, på hva kallet til hvilken funksjon? Hva slags spor gjør det gi meg? Og det er akkurat det slags tankesett som du skal komme inn når du er tenker debugging programmene dine. Jeg er Doug Lloyd. Dette er CS50.