1 00:00:00,000 --> 00:00:00,309 2 00:00:00,309 --> 00:00:02,350 [? DAN ARMADARAS:?] Hej, Jag är [? Dan Armadaras?]. 3 00:00:02,350 --> 00:00:04,410 Idag ska vi till att titta på felsökning. 4 00:00:04,410 --> 00:00:06,697 Inte bara kommer vi att prata om vissa tekniker, 5 00:00:06,697 --> 00:00:09,280 men också att vi kommer att titta på några av de funktioner som finns 6 00:00:09,280 --> 00:00:14,170 inom CS50 IDE som tillåter du enkelt felsöka ett program. 7 00:00:14,170 --> 00:00:16,272 >> Bara ett exempel på något som kan gå fel 8 00:00:16,272 --> 00:00:18,730 och det är faktiskt något att vi redan har sett förut. 9 00:00:18,730 --> 00:00:23,200 I det här fallet är det ett C-program som accepterar ett heltal från användaren, 10 00:00:23,200 --> 00:00:27,580 dividerar det med två, och tillhandahåller utsignalen tillbaka till användaren. 11 00:00:27,580 --> 00:00:30,610 Nu från vad vi har sett tidigare i föreläsningar, 12 00:00:30,610 --> 00:00:34,370 Vi vet att detta faktiskt kommer att orsaka specifika typer av division problem 13 00:00:34,370 --> 00:00:35,860 när vi har udda nummer. 14 00:00:35,860 --> 00:00:40,330 >> Specifikt ska vi bara kasta bort något efter decimalkommat. 15 00:00:40,330 --> 00:00:43,170 Nu vet vi att detta råkar vara fallet. 16 00:00:43,170 --> 00:00:47,430 Och om vi kör det, kan vi bekräfta våra misstankar, det första genom att sammanställa. 17 00:00:47,430 --> 00:00:50,460 Och sedan, genom att köra och ange ett udda tal. 18 00:00:50,460 --> 00:00:51,720 >> Detta är inget nytt. 19 00:00:51,720 --> 00:00:54,490 Men detta är faktiskt en exempel på en bugg som 20 00:00:54,490 --> 00:00:58,810 kan existera inom ett större program som blir svårare att spåra. 21 00:00:58,810 --> 00:01:02,640 Även om vi vet vad problemet är den verkliga springande punkten 22 00:01:02,640 --> 00:01:06,250 kanske försöker identifiera särskilt där felet uppstår, 23 00:01:06,250 --> 00:01:09,750 identifiera vad det problemet är, och sedan fastställa det. 24 00:01:09,750 --> 00:01:14,400 Så ge detta som ett exempel av vad som kan vara något 25 00:01:14,400 --> 00:01:19,030 att vi redan vet men kan begravas inom andra delar av koden. 26 00:01:19,030 --> 00:01:23,090 >> Så öppna denna annan källa kodfilen som ett exempel, 27 00:01:23,090 --> 00:01:27,165 denna uppdelning problemet är nu en del av ett större program. 28 00:01:27,165 --> 00:01:29,040 Fortfarande kan vara lite bitars krystat, och vi 29 00:01:29,040 --> 00:01:31,076 kanske kan enkelt identifiera det, särskilt 30 00:01:31,076 --> 00:01:32,450 eftersom vi bara diskutera detta. 31 00:01:32,450 --> 00:01:38,250 Men vi kan räkna ut att detta problem kan existera i en större skala. 32 00:01:38,250 --> 00:01:45,450 >> Om jag sammanställa detta och nu kör det, ange ett udda antal, 33 00:01:45,450 --> 00:01:49,816 Vi kan se att vi inte får exakt utgången att vi kan ha förväntat. 34 00:01:49,816 --> 00:01:51,690 I det aktuella fallet, Vi kan säga att vi 35 00:01:51,690 --> 00:01:56,060 vill räkna alla nummer från en upp till några specifika numret. 36 00:01:56,060 --> 00:01:58,130 Och vi kan se att vi har en rad olika frågor 37 00:01:58,130 --> 00:02:03,880 här om vi utmatning, helt enkelt, 0 och en när vi ger en ingång till 5. 38 00:02:03,880 --> 00:02:07,380 >> Så vi vet redan att det finns ett problem här. 39 00:02:07,380 --> 00:02:11,662 Men vi kanske inte vet exakt där denna fråga faktiskt existerar. 40 00:02:11,662 --> 00:02:13,620 Nu ett av de sätt som vi kan försöka åtgärda detta 41 00:02:13,620 --> 00:02:15,745 är något som vi har redan presenterats för. 42 00:02:15,745 --> 00:02:18,880 Vi kan bara använda den i större skala. 43 00:02:18,880 --> 00:02:21,680 >> På rad 14, har vi denna printf funktion, 44 00:02:21,680 --> 00:02:25,620 som tillåter oss att skriva ut staten av olika bitar av information. 45 00:02:25,620 --> 00:02:28,880 Och detta är något som du bör utnyttja inom ditt program 46 00:02:28,880 --> 00:02:33,100 att försöka ta reda på exakt vad som är händer i olika rader kod. 47 00:02:33,100 --> 00:02:36,350 Så även om detta inte är den slutresultatet att vi faktiskt 48 00:02:36,350 --> 00:02:39,830 vill producera slut detta program, vi fortfarande 49 00:02:39,830 --> 00:02:42,300 kanske har några debug uttalanden där vi 50 00:02:42,300 --> 00:02:46,970 kan försöka lista ut exakt vad händer inne i vår kod. 51 00:02:46,970 --> 00:02:51,210 >> Så i det här fallet, kommer jag printf med felsöknings taggen. 52 00:02:51,210 --> 00:02:53,540 I detta fall, är detta bara en felsöknings sträng 53 00:02:53,540 --> 00:02:56,840 att jag är uppe stötande så att det blir mycket tydligt i produktionen av min kod 54 00:02:56,840 --> 00:02:59,200 vad det är att jag vill visa. 55 00:02:59,200 --> 00:03:04,410 Och utgångs här numret att vi har beräknat. 56 00:03:04,410 --> 00:03:06,800 >> I det här fallet kanske jag vill veta exakt 57 00:03:06,800 --> 00:03:11,380 vad som händer före och efter vissa specifika beräkning. 58 00:03:11,380 --> 00:03:16,224 Så jag kan använda en printf innan och efter det kodrad. 59 00:03:16,224 --> 00:03:18,640 I det här fallet, jag kunde även gör det lite tydligare 60 00:03:18,640 --> 00:03:21,960 genom att säga debug innan och felsöka efter så 61 00:03:21,960 --> 00:03:26,540 att jag inte ihop mig med flera rader som ser identiska. 62 00:03:26,540 --> 00:03:32,290 >> Om vi ​​nu kompilera detta och kör det, ange en siffra som fem igen, 63 00:03:32,290 --> 00:03:35,090 Vi kan se att vi har nu ut innan och efter 64 00:03:35,090 --> 00:03:40,670 och upptäcker att vi inte har gjort en tydlig division eller tydlig med hur många 65 00:03:40,670 --> 00:03:43,680 att vi faktiskt vill göra. 66 00:03:43,680 --> 00:03:48,660 Nu i det här fallet, är detta inte riktigt en tydlig utgång. 67 00:03:48,660 --> 00:03:52,440 Det är egentligen inte en tydlig resultat som vi vill ha ut av detta program. 68 00:03:52,440 --> 00:03:54,427 >> Och detta är, återigen, en lite krystat. 69 00:03:54,427 --> 00:03:57,510 Men, kanske en av de saker som vi kunde göra om specifikationen sa 70 00:03:57,510 --> 00:04:01,900 att vi vill dela detta genom 2 och lägg 1-- så med andra ord, 71 00:04:01,900 --> 00:04:04,550 Vi vill att runda up-- sedan vi skulle veta att vi kunde 72 00:04:04,550 --> 00:04:08,060 gör det viss sak, i detta fall. 73 00:04:08,060 --> 00:04:14,010 Nu här vet vi att vi kommer att vara lägga till en till vår halverats nummer. 74 00:04:14,010 --> 00:04:16,490 >> Låt oss kompilera om detta och bekräfta att 75 00:04:16,490 --> 00:04:18,860 beter sig på det sätt som vi vill. 76 00:04:18,860 --> 00:04:21,980 Vi kan se att nu innan har, har vi nummer 5. 77 00:04:21,980 --> 00:04:26,620 Efter att ha, har vi siffran 3, vilket enligt vår specifikation, 78 00:04:26,620 --> 00:04:29,292 är vad vi ville göra. 79 00:04:29,292 --> 00:04:31,000 Men om vi tittar på utgång här, vi kan 80 00:04:31,000 --> 00:04:33,760 se till att vi kan ha en annan bug helt och hållet, vilket är 81 00:04:33,760 --> 00:04:36,940 att vi börjar vår räkning från 0. 82 00:04:36,940 --> 00:04:39,390 >> Nu återigen, detta är något som vi har sett i det förflutna 83 00:04:39,390 --> 00:04:42,500 och vi kan fixa ganska lätt. 84 00:04:42,500 --> 00:04:44,790 Men i det här fallet, vi hade också förmånen 85 00:04:44,790 --> 00:04:48,940 att använda printf uttalande direkt inne i for-slingan 86 00:04:48,940 --> 00:04:52,930 att veta exakt var att fel förekommer. 87 00:04:52,930 --> 00:04:55,150 Så printf uttalanden är mycket användbart för att hjälpa 88 00:04:55,150 --> 00:04:57,940 du bestämma var, just i din källkod, 89 00:04:57,940 --> 00:05:00,620 ett specifikt fel har inträffat. 90 00:05:00,620 --> 00:05:03,650 >> Och det är också viktigt att inse att när vi skriver kod, 91 00:05:03,650 --> 00:05:06,052 Vi kanske har antaganden om tillståndet i ett program. 92 00:05:06,052 --> 00:05:08,510 Eller vi kanske antaganden om vilken del av programmet 93 00:05:08,510 --> 00:05:13,020 är faktiskt rätt eller fel när senare när vi bygger på det programmet 94 00:05:13,020 --> 00:05:15,950 och göra den till en del av en komplexa och större program 95 00:05:15,950 --> 00:05:19,700 att vi inser att någon aspekt av detta är faktiskt paraplyvagn. 96 00:05:19,700 --> 00:05:22,680 >> Använda printf kan verkligen hjälpa begränsa och identifiera 97 00:05:22,680 --> 00:05:26,430 regionerna i ett program som inte kan beter sig precis så som vi 98 00:05:26,430 --> 00:05:29,500 förvänta, baserat på våra antaganden. 99 00:05:29,500 --> 00:05:31,460 Men det finns andra verktyg tillgängliga, liksom, 100 00:05:31,460 --> 00:05:34,860 som tillåter oss att försöka siffra ut var ett fel inträffar 101 00:05:34,860 --> 00:05:39,930 och även, specifikt, vad saker händer inne i programmet. 102 00:05:39,930 --> 00:05:41,990 >> Så använder printf är mycket användbart när vi vill 103 00:05:41,990 --> 00:05:45,900 att identifiera specifika områden ett program som har vissa programfel. 104 00:05:45,900 --> 00:05:47,730 Men det blir också tråkiga efter ett tag. 105 00:05:47,730 --> 00:05:50,500 I detta fall, är detta en relativt enkelt program 106 00:05:50,500 --> 00:05:52,750 med bara en eller två variabler. 107 00:05:52,750 --> 00:05:57,260 Och det blir mycket lätt för oss att skriva ut värdet av dessa variabler 108 00:05:57,260 --> 00:05:59,670 i samband med det större program. 109 00:05:59,670 --> 00:06:02,670 >> Men vi kan ha en annan program som har många variabler. 110 00:06:02,670 --> 00:06:06,530 Och det kan inte vara helt så lätt att använda printf 111 00:06:06,530 --> 00:06:10,120 för att försöka utvärdera vad som händer till var och en av dessa variabler 112 00:06:10,120 --> 00:06:13,590 eftersom programmet körs. 113 00:06:13,590 --> 00:06:16,960 Det finns ett program som existerar kallas en avlusarprogrammet. 114 00:06:16,960 --> 00:06:20,320 I det här fallet, det som vi kommer användning GNU debugger, eller GDB, 115 00:06:20,320 --> 00:06:24,260 som tillåter oss att inspektera den inre arbetet i ett program i en mycket mer 116 00:06:24,260 --> 00:06:25,700 detaljerat sätt. 117 00:06:25,700 --> 00:06:28,810 >> Vi kan faktiskt köra GDB från kommandoraden 118 00:06:28,810 --> 00:06:35,370 här genom att helt enkelt skriva GDB och kommando som vi vill felsöka. 119 00:06:35,370 --> 00:06:37,550 I det här fallet räknas. 120 00:06:37,550 --> 00:06:41,650 Nu i det här fallet, kan vi se att det leder oss till en prompt som säger GDB. 121 00:06:41,650 --> 00:06:44,020 Och vi kan faktiskt exekvera kommandon till GDB 122 00:06:44,020 --> 00:06:48,260 att faktiskt börja genomförandet av program, stoppa det på vissa punkter, 123 00:06:48,260 --> 00:06:51,060 utvärdera variablerna och inspektera variabler som 124 00:06:51,060 --> 00:06:54,152 finns i programtillståndet vid just det ögonblicket, 125 00:06:54,152 --> 00:06:55,110 och så vidare och så vidare. 126 00:06:55,110 --> 00:06:57,240 Det ger en hel del kraft till oss. 127 00:06:57,240 --> 00:06:59,960 >> Men det råkar vara så att CS50 IDE också 128 00:06:59,960 --> 00:07:05,870 ger en GUI eller en användare gränssnitt för GDB som 129 00:07:05,870 --> 00:07:11,120 tillåter oss att göra detta utan att behöva kommandoradsgränssnitt som helst 130 00:07:11,120 --> 00:07:13,560 eller överhuvudtaget ens. 131 00:07:13,560 --> 00:07:16,930 Det sätt som jag kan komma åt den är att använda debug-knappen 132 00:07:16,930 --> 00:07:20,120 högst upp på CS50 IDE. 133 00:07:20,120 --> 00:07:24,280 Nu i det förflutna, vad vi har sett är att vi använder kommandot 134 00:07:24,280 --> 00:07:27,660 linje att kompilera och sedan köra ett program. 135 00:07:27,660 --> 00:07:29,790 >> Debug knapp gör båda av dessa steg. 136 00:07:29,790 --> 00:07:34,380 Men det kommer också att ta upp debugger fliken längst till höger 137 00:07:34,380 --> 00:07:38,280 som tillåter oss att inspektera en mängd av egenskaper hos programmet 138 00:07:38,280 --> 00:07:40,500 eftersom det körs. 139 00:07:40,500 --> 00:07:44,280 Om jag klickar debug, i detta fall, kommer det att föra upp 140 00:07:44,280 --> 00:07:48,230 en ny flik i konsolen fönstret längst ner. 141 00:07:48,230 --> 00:07:51,160 >> Och du kan se att den här fliken har viss information högst upp. 142 00:07:51,160 --> 00:07:52,670 Och vi kan i stort sett bortse från detta. 143 00:07:52,670 --> 00:07:54,800 Men en av de saker att vi vill märka 144 00:07:54,800 --> 00:07:57,170 är att det avger samma sak som vi 145 00:07:57,170 --> 00:08:03,000 skulle få om vi försökte köra göra på C-programmet i terminalfönstret. 146 00:08:03,000 --> 00:08:06,230 >> Här kan vi se det körs klang, och det har en mängd olika flaggor, 147 00:08:06,230 --> 00:08:12,660 och det sammanställer vår count.c fil, vilket var den valda fliken vid tidpunkten 148 00:08:12,660 --> 00:08:15,100 att jag slog debug. 149 00:08:15,100 --> 00:08:18,010 Så det här är mycket användbar eftersom Nu använder denna debug-knappen, 150 00:08:18,010 --> 00:08:23,280 Vi kan samtidigt sammanställa och sedan exekvera program som vi faktiskt 151 00:08:23,280 --> 00:08:24,460 vill köra. 152 00:08:24,460 --> 00:08:27,880 >> En av de flaggor som är viktigt, i detta fall, 153 00:08:27,880 --> 00:08:30,190 Vi har faktiskt använt under längst tid 154 00:08:30,190 --> 00:08:32,450 men också bara gjorde vissa handen vinka [OHÖRBAR], som 155 00:08:32,450 --> 00:08:33,820 är detta en rätt här. 156 00:08:33,820 --> 00:08:35,790 I klang, säger -ggdb3. 157 00:08:35,790 --> 00:08:38,570 158 00:08:38,570 --> 00:08:41,250 I det här fallet, vad vi är träffande klang, vår kompilator, 159 00:08:41,250 --> 00:08:43,820 är att vi vill kompilera vårt program. 160 00:08:43,820 --> 00:08:46,810 Men också ge vad är kallas symbolinformation 161 00:08:46,810 --> 00:08:50,940 så att kompilatorn faktiskt har tillgång till en hel del av den underliggande informationen 162 00:08:50,940 --> 00:08:52,610 som finns i programmet. 163 00:08:52,610 --> 00:08:55,260 >> Mer specifikt, antalet funktioner som jag har, 164 00:08:55,260 --> 00:08:58,000 namnen på dessa funktioner, variablerna, de typer 165 00:08:58,000 --> 00:09:01,730 att dessa variabler är, och en mängd andra saker som hjälper debugger 166 00:09:01,730 --> 00:09:04,350 utföra sin verksamhet. 167 00:09:04,350 --> 00:09:06,600 Nu finns det något annat det är viktigt att nämna 168 00:09:06,600 --> 00:09:10,280 när vi diskuterar igång ett program på det här sättet. 169 00:09:10,280 --> 00:09:13,660 >> Lägg märke till att det faktiskt har tog upp en ny flik i vår konsol 170 00:09:13,660 --> 00:09:14,780 längs bottnen. 171 00:09:14,780 --> 00:09:18,600 Vi har inte längre att interagera direkt med terminalfönstret. 172 00:09:18,600 --> 00:09:21,420 Men denna nya flik är faktiskt ett terminalfönster. 173 00:09:21,420 --> 00:09:26,710 Det är bara specifika för driften program som vi har skapat. 174 00:09:26,710 --> 00:09:29,270 >> Lägg märke till att vid botten, i kombination med någon utgång 175 00:09:29,270 --> 00:09:33,500 genom klang kompilatorn och GDB, som vi till stor del ignorera, 176 00:09:33,500 --> 00:09:37,570 det faktiskt visar utsignalen från vårt program längst ner. 177 00:09:37,570 --> 00:09:41,240 Nu är det viktigt att inse att ett fönster faktiskt 178 00:09:41,240 --> 00:09:43,360 kommer att visa dig utdata från ditt program 179 00:09:43,360 --> 00:09:47,190 men också kan acceptera input för detta program, liksom. 180 00:09:47,190 --> 00:09:49,260 >> Så meddelande som säger ange en siffra, 181 00:09:49,260 --> 00:09:53,050 vilket är samma utgång som vi hade hade i terminalfönstret innan. 182 00:09:53,050 --> 00:09:55,510 Men det är nu visas i denna ny flik. 183 00:09:55,510 --> 00:09:56,550 Jag kan mata in ett nummer. 184 00:09:56,550 --> 00:10:00,900 Och det kommer faktiskt fungerar som vi förväntar oss 185 00:10:00,900 --> 00:10:05,890 visar oss vår debug, produktion, utgången som kan vara buggig, 186 00:10:05,890 --> 00:10:07,010 som vi har sett förut. 187 00:10:07,010 --> 00:10:10,460 Och längst ned, det faktiskt har några ytterligare utgång 188 00:10:10,460 --> 00:10:14,550 från BNP bara säga att detta program har avslutats. 189 00:10:14,550 --> 00:10:16,655 >> Nu när du såg i detta särskilt genomgång, 190 00:10:16,655 --> 00:10:19,370 det var inte särskilt användbar eftersom även 191 00:10:19,370 --> 00:10:23,740 även om vi hade debugger menyn kommer upp, det var fortfarande ett pågående program. 192 00:10:23,740 --> 00:10:26,790 Vid någon punkt gjorde det faktiskt pausa utförande för oss 193 00:10:26,790 --> 00:10:30,767 för att kunna inspektera alla variablerna packas däri. 194 00:10:30,767 --> 00:10:32,850 Det finns något annat att vi måste göra för att 195 00:10:32,850 --> 00:10:36,910 att få GDB att inse att vi vill ha att pausa genomförandet av programmet 196 00:10:36,910 --> 00:10:42,820 och inte bara låta den fortskrida normalt som vi skulle i alla andra fall. 197 00:10:42,820 --> 00:10:45,530 >> För att pausa utförande, vid någon viss linje, 198 00:10:45,530 --> 00:10:47,830 Vi måste skapa vad som är kallas en brytpunkt. 199 00:10:47,830 --> 00:10:52,670 Och en brytpunkt är mycket lätt skapas i detta CS50 IDE genom att ta musen 200 00:10:52,670 --> 00:10:57,090 och klicka direkt till vänster av vissa specifika linjenummer. 201 00:10:57,090 --> 00:10:59,920 När jag gör det, en röd prick visas, vilket indikerar 202 00:10:59,920 --> 00:11:02,300 att denna linje är nu en brytpunkt. 203 00:11:02,300 --> 00:11:07,540 >> Och nästa gång jag kör GDB, det kommer att stoppa exekvering vid den brytpunkt 204 00:11:07,540 --> 00:11:10,280 när den når den kodrad. 205 00:11:10,280 --> 00:11:12,230 Nu är en viktig sak att inse 206 00:11:12,230 --> 00:11:16,140 att det inte nödvändigtvis så att varje kodrad 207 00:11:16,140 --> 00:11:17,880 är verkligen tillgängliga. 208 00:11:17,880 --> 00:11:23,780 Om jag skulle skapa en funktion här uppe, för example-- void F-- 209 00:11:23,780 --> 00:11:31,230 och bara göra en utskrift linje här-- hello world-- om jag aldrig kalla denna funktion, 210 00:11:31,230 --> 00:11:34,770 det kommer att vara så att, om jag ställer en brytpunkt här, 211 00:11:34,770 --> 00:11:36,220 funktionen kommer aldrig att kallas. 212 00:11:36,220 --> 00:11:38,310 Och därför detta särskilt brytpunkt 213 00:11:38,310 --> 00:11:43,040 kommer aldrig paus genomförandet av programmet. 214 00:11:43,040 --> 00:11:48,020 >> Så låt oss säga att jag skapar rätt en brytpunkt på någon kodrad 215 00:11:48,020 --> 00:11:50,340 som faktiskt kommer att utföras. 216 00:11:50,340 --> 00:11:53,470 Nu i det här fallet, är detta första raden i huvudfunktionen. 217 00:11:53,470 --> 00:11:56,630 Så det kommer säkert att bli fallet att så fort jag börjar utförande, 218 00:11:56,630 --> 00:11:58,580 den allra första raden kommer att nås. 219 00:11:58,580 --> 00:12:00,230 GDB pausas exekveringen. 220 00:12:00,230 --> 00:12:04,100 Och då kommer jag att kunna interagera med debugger. 221 00:12:04,100 --> 00:12:08,480 >> Du kan ställa in flera rader som brytpunkter, om du vill. 222 00:12:08,480 --> 00:12:11,365 Vi kan också skapa en linje upp här i detta segment av kod 223 00:12:11,365 --> 00:12:12,490 som aldrig kommer att nås. 224 00:12:12,490 --> 00:12:14,744 Och vi kan också ställa ytterligare nedan. 225 00:12:14,744 --> 00:12:16,660 Anledningen till att vi skulle vill göra detta vi ska 226 00:12:16,660 --> 00:12:19,119 gå in lite mer detalj på bara ett ögonblick. 227 00:12:19,119 --> 00:12:21,660 Så för nu, låt mig bara inaktivera dessa ytterligare brytpunkter 228 00:12:21,660 --> 00:12:24,940 så att vi kan titta på vad som händer när jag har en enda paus 229 00:12:24,940 --> 00:12:27,650 punkt i mitt program. 230 00:12:27,650 --> 00:12:29,410 Jag har gjort några ändringar i detta program. 231 00:12:29,410 --> 00:12:30,750 Så jag måste spara det. 232 00:12:30,750 --> 00:12:34,490 Jag kommer att klicka debug så att jag kan påbörja sammanställning och sedan 233 00:12:34,490 --> 00:12:36,880 genomförandet av debugger. 234 00:12:36,880 --> 00:12:40,632 >> Vi kommer att se att, efter stunder, de linje som vi valt som paus 235 00:12:40,632 --> 00:12:43,360 punkt gulmarkerad. 236 00:12:43,360 --> 00:12:47,440 Vi kan också notera att i övre högra i felsökningspanelen 237 00:12:47,440 --> 00:12:50,940 att pausikonen har vänt i en liten spelikonen. 238 00:12:50,940 --> 00:12:54,710 Det innebär att vi har paus utförande, i det här fallet. 239 00:12:54,710 --> 00:12:57,840 Och slå på knappen Spela skulle tillåter oss att återuppta exekveringen 240 00:12:57,840 --> 00:13:00,000 vid denna punkt. 241 00:13:00,000 --> 00:13:03,240 >> Lägg märke till att det finns ett par andra knappar som i denna debug panel, 242 00:13:03,240 --> 00:13:04,220 också. 243 00:13:04,220 --> 00:13:09,470 Kliva över, vilket gör att jag kan verkställa det en kodrad 244 00:13:09,470 --> 00:13:14,030 och steg över till den linjen till nästa ett, som, i detta fall, 245 00:13:14,030 --> 00:13:17,060 skulle innebära att printf satsen körs. 246 00:13:17,060 --> 00:13:22,310 Och den kommer sedan paus exekvering på ledningen 13, som så. 247 00:13:22,310 --> 00:13:25,090 >> Och det är också ett steg i funktion, som 248 00:13:25,090 --> 00:13:28,950 är bra om jag har skapat andra fungerar på andra håll i källkoden. 249 00:13:28,950 --> 00:13:31,420 Och jag vill kliva in dessa funktioner snarare än 250 00:13:31,420 --> 00:13:33,050 exekvera denna funktion i dess helhet. 251 00:13:33,050 --> 00:13:37,279 Men vi kommer att titta mer på steget i funktion på bara ett ögonblick. 252 00:13:37,279 --> 00:13:40,320 Nu märka några andra saker som faktiskt finns inom denna debug panel. 253 00:13:40,320 --> 00:13:44,110 >> Vi har denna panel som kallas call stack, som visar oss 254 00:13:44,110 --> 00:13:45,300 exakt var vi är. 255 00:13:45,300 --> 00:13:48,550 I det här fallet är vi innanför av huvudfunktionen. 256 00:13:48,550 --> 00:13:50,880 Vårt manus kallas count.c. 257 00:13:50,880 --> 00:13:53,820 Och vi råkar vara på linje 13, kolumn ett, vilket 258 00:13:53,820 --> 00:13:58,950 är exakt vad den markerade regionen av källkoden indikerar, liksom. 259 00:13:58,950 --> 00:14:02,435 >> Nu märker att detta visar också enligt den lokala rörliga delen 260 00:14:02,435 --> 00:14:06,710 alla de variabler som existerar inom denna funktion. 261 00:14:06,710 --> 00:14:08,930 Det är viktigt att notera att alla de variabler 262 00:14:08,930 --> 00:14:12,580 kommer att visas i denna lokal variabel sektion inom en funktion, 263 00:14:12,580 --> 00:14:14,380 redan innan de definieras. 264 00:14:14,380 --> 00:14:19,160 Vi kan se här att vi har en variabel kallas num har ett standardvärde på 0, 265 00:14:19,160 --> 00:14:21,280 och det är av typen int. 266 00:14:21,280 --> 00:14:24,110 >> Nu innan vi faktiskt initiera alla dessa variabler, 267 00:14:24,110 --> 00:14:26,685 vi är inte nödvändigtvis garanterat att se ett värde av 0. 268 00:14:26,685 --> 00:14:29,200 Och beroende på andra avrättningar att du har utfört 269 00:14:29,200 --> 00:14:32,020 och läget i ditt minne när du faktiskt köra programmet, 270 00:14:32,020 --> 00:14:34,605 du kanske upptäcker att du ser inte värdet 0 271 00:14:34,605 --> 00:14:36,550 och, i stället, vissa andra galna siffror. 272 00:14:36,550 --> 00:14:38,390 >> Men oroa dig inte om det. 273 00:14:38,390 --> 00:14:44,610 Det kommer inte att vara relevant tills du faktiskt initiera värdet. 274 00:14:44,610 --> 00:14:49,630 Nu i det här fallet, kan vi se att Jag har utfört några utgångar. 275 00:14:49,630 --> 00:14:52,131 Och jag, just nu, pausade utförande. 276 00:14:52,131 --> 00:14:53,880 Men i detta fall, vad Jag vill verkligen göra 277 00:14:53,880 --> 00:14:58,060 är nu kliva över denna linje kod så att jag kan faktiskt 278 00:14:58,060 --> 00:15:04,390 fråga användaren för att int som Vi vill använda i vårt program. 279 00:15:04,390 --> 00:15:07,060 >> Nu i det här fallet, när Jag slog steg över, meddelande 280 00:15:07,060 --> 00:15:11,940 att Paus eller snarare Resume knappen har ändrats till denna pausknappen 281 00:15:11,940 --> 00:15:14,022 eftersom denna kod faktiskt utför. 282 00:15:14,022 --> 00:15:15,730 Vad händer just nu är att det är 283 00:15:15,730 --> 00:15:21,630 väntar på oss för att mata in viss information som vi kan se från vår produktion text 284 00:15:21,630 --> 00:15:23,600 längst ner. 285 00:15:23,600 --> 00:15:25,787 >> Så just nu är det faktiskt inte stannade, 286 00:15:25,787 --> 00:15:28,620 även om det slags verkar att vara eftersom ingenting händer. 287 00:15:28,620 --> 00:15:32,360 Men det råkar vara så att mitt specifika fall på rad 13, 288 00:15:32,360 --> 00:15:34,210 Jag väntar på indata från användaren. 289 00:15:34,210 --> 00:15:39,130 Och så GDB inte kan inspektera ett program som det körs. 290 00:15:39,130 --> 00:15:43,370 >> Nu nästa gång jag kommer in några input-- så jag kommer in som nummer 5, 291 00:15:43,370 --> 00:15:46,140 som vi har sett i past-- hit Return, och vi 292 00:15:46,140 --> 00:15:51,430 märka det, omedelbart, GDB pauser och, återigen, belyser nästa rad. 293 00:15:51,430 --> 00:15:55,320 Men märker att nu, som en Resultatet av vår inmatning av ett värde, 294 00:15:55,320 --> 00:15:58,930 Vi har uppdaterat detta värde inne av våra lokala variabler, som 295 00:15:58,930 --> 00:16:05,560 är mycket bra att veta exakt vad det numret var i minnet. 296 00:16:05,560 --> 00:16:10,650 >> Nu kan jag låta detta program för att fortsätta spela fram till slutet av dess genomförande 297 00:16:10,650 --> 00:16:12,570 genom att trycka på Fortsätt. 298 00:16:12,570 --> 00:16:16,410 Vi kan se att mycket snabbt gör programmet avsluta verkställande 299 00:16:16,410 --> 00:16:19,790 med samma utgång som vi hade tidigare, debugger stänger, 300 00:16:19,790 --> 00:16:23,170 och nu det här programmet har stannat helt. 301 00:16:23,170 --> 00:16:25,320 >> I visar att bara för syfte att se vad 302 00:16:25,320 --> 00:16:27,280 händer när vi faktiskt drabbats Resume. 303 00:16:27,280 --> 00:16:30,640 Men vi faktiskt kommer att vill gå tillbaka till det här programmet 304 00:16:30,640 --> 00:16:33,820 så att vi kan försöka att felsöka exakt vad som händer. 305 00:16:33,820 --> 00:16:37,980 Nu när jag använder debugger, kan jag inte behöver dessa felsöknings printf uttalanden. 306 00:16:37,980 --> 00:16:43,860 >> Så jag kunde ta bort dem som jag kommer att göra nu bara att gå tillbaka till vår enklare kod 307 00:16:43,860 --> 00:16:45,950 att vi hade för en stund sedan. 308 00:16:45,950 --> 00:16:48,790 Nu när jag sparar programmera och köra den, 309 00:16:48,790 --> 00:16:53,700 Det kommer återigen gå till den första bryta punkt som jag hade på linje 11. 310 00:16:53,700 --> 00:16:57,700 Och jag kommer att kunna inspektera mina variabler som jag vill göra. 311 00:16:57,700 --> 00:17:00,695 >> Det råkar vara så att detta del är inte särskilt intressant, 312 00:17:00,695 --> 00:17:04,364 Och jag vet att jag kommer att skriva ut detta uttalande. 313 00:17:04,364 --> 00:17:05,280 Ange ett nummer. 314 00:17:05,280 --> 00:17:08,099 Och sedan, jag vet att jag kommer att fråga användaren om det heltal. 315 00:17:08,099 --> 00:17:13,329 Så kanske jag faktiskt vill flytta min brytpunkt lite längre ner. 316 00:17:13,329 --> 00:17:16,710 >> Du kan ta bort brytpunkter genom att klicka igen, direkt 317 00:17:16,710 --> 00:17:18,460 till vänster om den linjen numret. 318 00:17:18,460 --> 00:17:22,200 Det röda pricken försvinner, vilket tyder att denna brytpunkt nu är borta. 319 00:17:22,200 --> 00:17:24,780 Nu i det här fallet, utförande har pausats. 320 00:17:24,780 --> 00:17:27,770 Och så det är inte faktiskt kommer att återupptas i detta speciella fall. 321 00:17:27,770 --> 00:17:30,210 Men jag kan ställa in en paus led lite senare. 322 00:17:30,210 --> 00:17:33,880 >> Och när jag nu återuppta min kod, kommer det att återuppta och berätta 323 00:17:33,880 --> 00:17:36,190 poängen med att brytpunkten. 324 00:17:36,190 --> 00:17:37,374 Återigen, jag slog Resume. 325 00:17:37,374 --> 00:17:39,040 Verkar inte som någonting som händer. 326 00:17:39,040 --> 00:17:41,450 Men det beror på min kod väntar på inmatning. 327 00:17:41,450 --> 00:17:47,900 Jag kommer att gå in ett antal 5, tryck Enter, och nu nästa brytpunkt kommer att drabbas. 328 00:17:47,900 --> 00:17:50,570 >> Nu i det här fallet, det här är kodraden 329 00:17:50,570 --> 00:17:53,820 att före, vi visste råkade vara buggy. 330 00:17:53,820 --> 00:17:57,590 Så låt oss utvärdera vad som händer vid denna särskilda tidpunkt. 331 00:17:57,590 --> 00:18:02,620 När en rad är markerad, detta linje ännu inte verkställts. 332 00:18:02,620 --> 00:18:06,490 Så i det här fallet, kan vi se att jag har ett antal, som 333 00:18:06,490 --> 00:18:11,610 Jag har ett heltal kallas num som har ett värde 5. 334 00:18:11,610 --> 00:18:15,090 Och jag kommer att utföra några matematik på det numret. 335 00:18:15,090 --> 00:18:20,130 >> Om jag kliva över det, vi kan Observera att värdet för num 336 00:18:20,130 --> 00:18:23,780 har förändrats i enlighet med det uträkningar som vi faktiskt har gjort. 337 00:18:23,780 --> 00:18:26,810 Och nu när vi är insidan av denna för loop 338 00:18:26,810 --> 00:18:29,090 eller nu när for-slingan själv är markerat 339 00:18:29,090 --> 00:18:32,450 ser vi att vi har en ny variabel som heter i att 340 00:18:32,450 --> 00:18:35,370 kommer att användas i den för slingan. 341 00:18:35,370 --> 00:18:38,230 >> Nu minns innan jag nämnde att du ibland är 342 00:18:38,230 --> 00:18:43,470 kommer att se något slags galen siffror som standard innan det numret 343 00:18:43,470 --> 00:18:45,530 eller att variabeln är faktiskt initieras. 344 00:18:45,530 --> 00:18:49,040 Vi kan se att just här i denna variabel 345 00:18:49,040 --> 00:18:51,345 kallas i, som inte har Ännu initierats 346 00:18:51,345 --> 00:18:53,560 vid tidpunkten för att lyfta fram. 347 00:18:53,560 --> 00:18:57,070 Men vi kan se att det har ett visst antal att vi faktiskt inte skulle förvänta sig. 348 00:18:57,070 --> 00:18:57,620 >> Det är ok. 349 00:18:57,620 --> 00:18:59,661 Oroa dig inte för det eftersom vi har faktiskt inte 350 00:18:59,661 --> 00:19:04,970 initieras det numret tills jag steg över denna linje och värdet 351 00:19:04,970 --> 00:19:08,560 Jag har initierats till värdet 1. 352 00:19:08,560 --> 00:19:11,400 Så för att se att det är faktiskt fallet, låt oss kliva över. 353 00:19:11,400 --> 00:19:14,420 Vi kan nu se att det linje har verkställts. 354 00:19:14,420 --> 00:19:17,000 Och vi nu lyfta fram denna printf linje. 355 00:19:17,000 --> 00:19:22,230 >> Och vi kan nu se hur våra värderingar av i och 3 har förändrats över tiden. 356 00:19:22,230 --> 00:19:26,450 Detta är mycket användbart för att göra, i själva verket är att kliva över linjer flera gånger. 357 00:19:26,450 --> 00:19:30,480 Och du kan hitta vad som egentligen händer inuti din för loop 358 00:19:30,480 --> 00:19:33,660 och vad som händer med variabler inne i den för loop 359 00:19:33,660 --> 00:19:39,200 som programexekvering uppstår ett steg i taget. 360 00:19:39,200 --> 00:19:41,110 >> Nu vid denna tidpunkt, jag klev över bara tillräckligt 361 00:19:41,110 --> 00:19:44,210 att jag nu i slutet av mitt program. 362 00:19:44,210 --> 00:19:46,980 Om jag kliva över det, kommer det faktiskt upphöra exekvering 363 00:19:46,980 --> 00:19:48,860 som vi har sett tidigare. 364 00:19:48,860 --> 00:19:52,110 Låt mig starta om, ännu en gång, så att jag kan peka något annat ut, 365 00:19:52,110 --> 00:19:53,320 också. 366 00:19:53,320 --> 00:19:55,350 >> I detta fall är det Nu frågar mig, igen, 367 00:19:55,350 --> 00:19:57,100 efter ett nummer som Jag kommer igen, anger. 368 00:19:57,100 --> 00:20:00,300 Men den här gången kommer jag att gå in i ett större antal så att för slingan 369 00:20:00,300 --> 00:20:02,540 kommer iterera fler gånger. 370 00:20:02,540 --> 00:20:06,090 I det här fallet kommer jag att ange ett värde av 11. 371 00:20:06,090 --> 00:20:08,390 >> Nu igen eftersom jag skulle ställa en brytpunkt vid linjen 15, 372 00:20:08,390 --> 00:20:10,490 det kommer att belysa den linjen. 373 00:20:10,490 --> 00:20:12,980 Vi kan se att vår nummer 11 är korrekt 374 00:20:12,980 --> 00:20:15,560 representerade i våra lokala variabler. 375 00:20:15,560 --> 00:20:22,460 Kliva över det, kan vi nu titta vad som händer med vårt värde i 376 00:20:22,460 --> 00:20:25,680 som vi fortsätter inne i detta för loop. 377 00:20:25,680 --> 00:20:31,960 Det blir ökas varje gång vi nå toppen av den för loop. 378 00:20:31,960 --> 00:20:35,110 >> Nu en av de saker som kanske vara bra att göra under exekvering 379 00:20:35,110 --> 00:20:40,490 av detta program är för mig att faktiskt ändra variablerna midstream att se 380 00:20:40,490 --> 00:20:42,450 vad som händer med mitt program. 381 00:20:42,450 --> 00:20:46,540 I det här fallet kan jag faktiskt Dubbelklicka på värdet. 382 00:20:46,540 --> 00:20:48,040 Lägg märke till att det blir ett textfält. 383 00:20:48,040 --> 00:20:50,280 >> Nu kan jag gå in olika värde helt och hållet 384 00:20:50,280 --> 00:20:55,700 att se hur mitt program beter när jag har ändrat den variabeln. 385 00:20:55,700 --> 00:20:59,560 Nu i detta fall den variabla I innehåller nu värdet 10. 386 00:20:59,560 --> 00:21:02,810 Men programmet är fortfarande paus i utförandet. 387 00:21:02,810 --> 00:21:07,610 När jag steg över, ser jag att värde i, som jag gick in som 10, 388 00:21:07,610 --> 00:21:12,170 inte är större än värdet av num, som omedelbart orsakar för slingan 389 00:21:12,170 --> 00:21:14,240 att sluta utföra. 390 00:21:14,240 --> 00:21:16,210 >> Nu är inte den enda anledningen till att du skulle 391 00:21:16,210 --> 00:21:19,450 vill ändra variabeln på plats. 392 00:21:19,450 --> 00:21:22,210 Du kan faktiskt vill att försöka ändra den så 393 00:21:22,210 --> 00:21:24,590 att du kan fortsätta exekvering av en slinga 394 00:21:24,590 --> 00:21:27,370 eller så att du kan ändra visst värde innan den 395 00:21:27,370 --> 00:21:32,630 når någon specifik uppsättning av aritmetik att du är på väg att utföra. 396 00:21:32,630 --> 00:21:36,210 >> Så nu när vi faktiskt förändra värde i som programmet kördes, 397 00:21:36,210 --> 00:21:39,540 Det orsakade för slinga för att sluta i förtid på grund, helt plötsligt, i 398 00:21:39,540 --> 00:21:42,770 råkade vara större än värdet av num, vilket innebär att det för loop 399 00:21:42,770 --> 00:21:45,410 inte längre behövs som skall exekveras. 400 00:21:45,410 --> 00:21:48,780 Vidare, hände det att vara så att vi ändrat värdet av i 401 00:21:48,780 --> 00:21:53,270 när linjen 17 betonades, som var den tidpunkt 402 00:21:53,270 --> 00:21:56,280 att för utförande slingan faktiskt utvärderas. 403 00:21:56,280 --> 00:22:00,210 >> Om jag hade ändrat värdet för i på en annan linje, säger 19, 404 00:22:00,210 --> 00:22:03,360 vi skulle ha sett annorlunda beteende eftersom linje 19 skulle 405 00:22:03,360 --> 00:22:08,310 har utfört före slingan villkoret omprövas. 406 00:22:08,310 --> 00:22:11,900 Nu vid denna tidpunkt, jag, återigen, vid slutet av detta program. 407 00:22:11,900 --> 00:22:15,707 Och jag kan låta detta gå till låta mitt program att sluta naturligt. 408 00:22:15,707 --> 00:22:18,290 Men det finns ett par saker som är viktigt att ta bort 409 00:22:18,290 --> 00:22:19,960 från just denna diskussion. 410 00:22:19,960 --> 00:22:22,490 Du måste utvärdera dina egna antaganden 411 00:22:22,490 --> 00:22:24,710 om hur koden ska bete sig. 412 00:22:24,710 --> 00:22:28,220 Varje gång du tror att någon bit kod du vet händer att arbeta, 413 00:22:28,220 --> 00:22:30,940 som kan vara en röd flagga för att gå tillbaka och utvärdera, och vara säker 414 00:22:30,940 --> 00:22:33,470 att ditt antagande av hur den koden fungerar 415 00:22:33,470 --> 00:22:38,290 är faktiskt sant för hur det är uttryckt i källkoden. 416 00:22:38,290 --> 00:22:41,300 >> Men ännu mer till punkt var, när vi använder debugger, 417 00:22:41,300 --> 00:22:43,920 du kan sätta brytpunkter på olika rader kod, 418 00:22:43,920 --> 00:22:48,110 vilket gör att debugger till pausa exekvering vid var och en av dessa linjer 419 00:22:48,110 --> 00:22:52,210 så att du kan utvärdera minne eller ens ändra det på plats. 420 00:22:52,210 --> 00:22:55,630 Och återigen, kom ihåg att du kan skapa flera brytpunkter så att du 421 00:22:55,630 --> 00:23:00,390 kan också återuppta utförande, hoppa över stora delar av kod, 422 00:23:00,390 --> 00:23:04,790 och det kommer automatiskt att pausa vid nästa brytpunkt. 423 00:23:04,790 --> 00:23:07,760 >> Det är faktiskt mer avancerad Utmärkande för debugger, liksom. 424 00:23:07,760 --> 00:23:10,170 Men vi måste hänvisa dig till vissa efterföljande videoklipp 425 00:23:10,170 --> 00:23:14,090 För att verkligen retas isär hur att använda dessa särskilda funktioner. 426 00:23:14,090 --> 00:23:15,990 För nu, tack mycket för att titta på. 427 00:23:15,990 --> 00:23:18,080 Och lycka till felsökning.