1 00:00:00,000 --> 00:00:00,309 2 00:00:00,309 --> 00:00:02,350 [? DAN ARMADARAS:?] Ciao, Sono [? Dan Armadaras?]. 3 00:00:02,350 --> 00:00:04,410 Oggi, stiamo andando a essere guardando il debug. 4 00:00:04,410 --> 00:00:06,697 Non solo abbiamo intenzione di parlare di alcune tecniche, 5 00:00:06,697 --> 00:00:09,280 ma anche noi stiamo andando a guardare alcune delle caratteristiche contenute 6 00:00:09,280 --> 00:00:14,170 all'interno dell'IDE CS50 che permettono di eseguire il debug di un programma facilmente. 7 00:00:14,170 --> 00:00:16,272 >> Un esempio di qualcosa che può andare storto 8 00:00:16,272 --> 00:00:18,730 e in realtà è qualcosa che abbiamo già visto in precedenza. 9 00:00:18,730 --> 00:00:23,200 In questo caso, questo è un programma C che accetta un numero intero da parte dell'utente, 10 00:00:23,200 --> 00:00:27,580 divide per due, e fornisce l'uscita di nuovo all'utente. 11 00:00:27,580 --> 00:00:30,610 Ora da quello che abbiamo visto in precedenza in lezioni, 12 00:00:30,610 --> 00:00:34,370 sappiamo che questo sarà effettivamente causare specifici tipi di problemi di divisione 13 00:00:34,370 --> 00:00:35,860 quando abbiamo i numeri dispari. 14 00:00:35,860 --> 00:00:40,330 >> In particolare, ci limiteremo a buttiamo nulla dopo il punto decimale. 15 00:00:40,330 --> 00:00:43,170 Ora, sappiamo che questo sembra essere il caso. 16 00:00:43,170 --> 00:00:47,430 E se corriamo, possiamo confermare i nostri sospetti, primo, mediante la compilazione. 17 00:00:47,430 --> 00:00:50,460 E poi, correndo e l'inserimento di un numero dispari. 18 00:00:50,460 --> 00:00:51,720 >> Non è una novità. 19 00:00:51,720 --> 00:00:54,490 Ma questo è in realtà un esempio di un bug che 20 00:00:54,490 --> 00:00:58,810 può esistere all'interno di un programma più ampio che diventa più difficile da rintracciare. 21 00:00:58,810 --> 00:01:02,640 Anche se sappiamo che cosa l'edizione è, il vero nocciolo della questione 22 00:01:02,640 --> 00:01:06,250 potrebbe essere cercando di identificare in particolare in cui si verifica l'errore, 23 00:01:06,250 --> 00:01:09,750 identificazione di ciò che problema è, e successivo fissaggio. 24 00:01:09,750 --> 00:01:14,400 Quindi fornire questo come un esempio di ciò che potrebbe essere qualcosa 25 00:01:14,400 --> 00:01:19,030 che già sappiamo, ma possiamo essere sepolti all'interno di altri elementi del codice. 26 00:01:19,030 --> 00:01:23,090 >> Quindi, l'apertura di questo altra fonte file di codice come esempio, 27 00:01:23,090 --> 00:01:27,165 questo problema di divisione è ora parte di un programma più grande. 28 00:01:27,165 --> 00:01:29,040 Ancora potrebbe essere un po bit artificiosa, e noi 29 00:01:29,040 --> 00:01:31,076 potrebbe essere in grado di facilità identificare, soprattutto 30 00:01:31,076 --> 00:01:32,450 dato che siamo solo a discutere di questo. 31 00:01:32,450 --> 00:01:38,250 Ma possiamo capire che questo problema può esistere su una scala più ampia. 32 00:01:38,250 --> 00:01:45,450 >> Se compilo questo e ora eseguirlo, immettere un numero dispari, 33 00:01:45,450 --> 00:01:49,816 possiamo vedere che non otteniamo esattamente l'uscita che forse abbiamo aspettato. 34 00:01:49,816 --> 00:01:51,690 In questo caso particolare, potremmo dire che siamo 35 00:01:51,690 --> 00:01:56,060 vogliono contare tutti i numeri da uno fino a qualche numero specifico. 36 00:01:56,060 --> 00:01:58,130 E possiamo vedere che abbiamo hanno una varietà di questioni 37 00:01:58,130 --> 00:02:03,880 qui se stiamo producendo, semplicemente, 0 e 1 quando mettiamo a disposizione un ingresso di 5. 38 00:02:03,880 --> 00:02:07,380 >> Così sappiamo già che c'è un problema qui. 39 00:02:07,380 --> 00:02:11,662 Ma non possiamo sapere con precisione dove questo problema esiste realmente. 40 00:02:11,662 --> 00:02:13,620 Ora, uno dei modi in cui possiamo cercare di risolvere questo problema 41 00:02:13,620 --> 00:02:15,745 è qualcosa che abbiamo già stato introdotto a. 42 00:02:15,745 --> 00:02:18,880 Possiamo solo utilizzare su una scala più ampia. 43 00:02:18,880 --> 00:02:21,680 >> Sulla linea 14, abbiamo questa funzione printf, 44 00:02:21,680 --> 00:02:25,620 che ci permette di stampare lo stato dei vari pezzi di informazioni. 45 00:02:25,620 --> 00:02:28,880 E questo è qualcosa che si dovrebbe sfruttare all'interno del programma 46 00:02:28,880 --> 00:02:33,100 per cercare di capire esattamente che cosa è accadendo in varie linee di codice. 47 00:02:33,100 --> 00:02:36,350 Quindi, anche se questo non è il output finale che in realtà 48 00:02:36,350 --> 00:02:39,830 vogliono produrre fuori questo programma, abbiamo ancora 49 00:02:39,830 --> 00:02:42,300 potrebbe avere qualche di debug dichiarazioni dove siamo 50 00:02:42,300 --> 00:02:46,970 può cercare di capire esattamente ciò che sta accadendo all'interno del nostro codice. 51 00:02:46,970 --> 00:02:51,210 >> Quindi, in questo caso, lo farò printf con il tag di debug. 52 00:02:51,210 --> 00:02:53,540 In questo caso, si tratta solo una stringa di debug 53 00:02:53,540 --> 00:02:56,840 che sono up-putting in modo che diventi molto chiaro nel uscita del mio codice 54 00:02:56,840 --> 00:02:59,200 che cosa è che voglio mostrare. 55 00:02:59,200 --> 00:03:04,410 E l'uscita qui il numero che abbiamo calcolato. 56 00:03:04,410 --> 00:03:06,800 >> In questo caso, potrei vogliono sapere con precisione 57 00:03:06,800 --> 00:03:11,380 quello che sta accadendo, prima e dopo qualche calcolo specifico. 58 00:03:11,380 --> 00:03:16,224 Così potrei usare un printf prima e dopo quella linea di codice. 59 00:03:16,224 --> 00:03:18,640 In questo caso, ho potuto anche renderlo un po 'più chiaro 60 00:03:18,640 --> 00:03:21,960 dicendo di debug prima ed eseguire il debug dopo così 61 00:03:21,960 --> 00:03:26,540 che io non confondo con me stesso più linee che sembrano identici. 62 00:03:26,540 --> 00:03:32,290 >> Ora, se questo ricompila e corsa esso, immettere un numero come cinque di nuovo, 63 00:03:32,290 --> 00:03:35,090 possiamo vedere che abbiamo Ora uscita prima e dopo 64 00:03:35,090 --> 00:03:40,670 e scopriamo che non abbiamo fatto un chiaro divisione o chiaro con il numero 65 00:03:40,670 --> 00:03:43,680 che in realtà vogliamo fare. 66 00:03:43,680 --> 00:03:48,660 Ora, in questo caso, si tratta non proprio una uscita chiara. 67 00:03:48,660 --> 00:03:52,440 Non è proprio un risultato chiaro che vogliamo da questo particolare programma. 68 00:03:52,440 --> 00:03:54,427 >> E questo è, ancora, un pò forzato. 69 00:03:54,427 --> 00:03:57,510 Ma, forse, una delle cose che potremmo fare se la specifica detto 70 00:03:57,510 --> 00:04:01,900 che vogliamo dividere questo per 2 e aggiungere 1-- così in altre parole, 71 00:04:01,900 --> 00:04:04,550 vogliamo arrotondare up-- poi potremmo sapere che abbiamo potuto 72 00:04:04,550 --> 00:04:08,060 fare quella cosa particolare, in questo caso. 73 00:04:08,060 --> 00:04:14,010 Ora qui sappiamo che saremo in grado di aggiungere 1 al nostro numero dimezzato. 74 00:04:14,010 --> 00:04:16,490 >> Cerchiamo di ricompilare questo e confermare che questo 75 00:04:16,490 --> 00:04:18,860 si sta comportando il modo in cui vogliamo. 76 00:04:18,860 --> 00:04:21,980 Possiamo vedere che ora prima avendo, abbiamo il numero 5. 77 00:04:21,980 --> 00:04:26,620 Dopo aver, abbiamo il numero 3, che secondo la nostra specifica, 78 00:04:26,620 --> 00:04:29,292 è quello che volevamo fare. 79 00:04:29,292 --> 00:04:31,000 Ma se guardiamo al uscita qui, possiamo 80 00:04:31,000 --> 00:04:33,760 vedere che potremmo avere un altro bug del tutto, che è 81 00:04:33,760 --> 00:04:36,940 che stiamo iniziando il nostro conteggio da 0. 82 00:04:36,940 --> 00:04:39,390 >> Ora di nuovo, questo è qualcosa che abbiamo visto in passato 83 00:04:39,390 --> 00:04:42,500 e siamo in grado di risolvere abbastanza prontamente. 84 00:04:42,500 --> 00:04:44,790 Ma in questo caso, ci anche avuto il vantaggio 85 00:04:44,790 --> 00:04:48,940 di utilizzare l'istruzione printf direttamente all'interno del ciclo for 86 00:04:48,940 --> 00:04:52,930 sapere esattamente dove tale errore stava accadendo. 87 00:04:52,930 --> 00:04:55,150 Dichiarazioni così printf sono molto utile per aiutare 88 00:04:55,150 --> 00:04:57,940 a determinare dove, precisamente nel codice sorgente, 89 00:04:57,940 --> 00:05:00,620 un errore specifico si sta verificando. 90 00:05:00,620 --> 00:05:03,650 >> Ed è anche importante rendersi conto che, come stiamo scrivendo codice, 91 00:05:03,650 --> 00:05:06,052 potremmo avere assunzioni sullo stato di un programma. 92 00:05:06,052 --> 00:05:08,510 Oppure potremmo avere assunzioni su quale parte del programma 93 00:05:08,510 --> 00:05:13,020 in realtà è giusta o sbagliata quando in seguito come si costruisce su quel programma 94 00:05:13,020 --> 00:05:15,950 e renderlo parte di un complesso e programma più ampio 95 00:05:15,950 --> 00:05:19,700 che ci rendiamo conto che alcuni aspetti di che in realtà è bacato. 96 00:05:19,700 --> 00:05:22,680 >> Usando printf può davvero aiutare restringere e identificare 97 00:05:22,680 --> 00:05:26,430 le regioni di un programma che non può comportarsi esattamente il modo in cui 98 00:05:26,430 --> 00:05:29,500 aspettarsi, in base alle nostre supposizioni. 99 00:05:29,500 --> 00:05:31,460 Ma ci sono altri strumenti disponibile, così, 100 00:05:31,460 --> 00:05:34,860 che ci permettono di cercare di capire dove un errore si verifica 101 00:05:34,860 --> 00:05:39,930 e anche, in particolare, ciò che le cose sono accadendo all'interno del programma. 102 00:05:39,930 --> 00:05:41,990 >> Quindi, utilizzando printf è molto quando utile vogliamo 103 00:05:41,990 --> 00:05:45,900 di individuare specifiche aree di un programma che ha qualche bug. 104 00:05:45,900 --> 00:05:47,730 Ma diventa anche noioso dopo un po '. 105 00:05:47,730 --> 00:05:50,500 In questo caso, si tratta di un relativamente semplice programma 106 00:05:50,500 --> 00:05:52,750 con solo uno o due variabili. 107 00:05:52,750 --> 00:05:57,260 E diventa molto facile per noi stampare il valore di tali variabili 108 00:05:57,260 --> 00:05:59,670 nell'ambito del programma più grande. 109 00:05:59,670 --> 00:06:02,670 >> Ma potremmo avere un diverso programma che ha molte variabili. 110 00:06:02,670 --> 00:06:06,530 E non può essere abbastanza così facile da usare printf 111 00:06:06,530 --> 00:06:10,120 per cercare di valutare ciò che sta accadendo a ciascuno di tali variabili 112 00:06:10,120 --> 00:06:13,590 come il programma sta eseguendo. 113 00:06:13,590 --> 00:06:16,960 C'è un programma che esiste chiamato un programma di debugger. 114 00:06:16,960 --> 00:06:20,320 In questo caso, quella che ci sarà utilizzo è il debugger GNU, o GDB, 115 00:06:20,320 --> 00:06:24,260 che ci permette di ispezionare l'interno funzionamento di un programma in modo molto più 116 00:06:24,260 --> 00:06:25,700 maniera dettagliata. 117 00:06:25,700 --> 00:06:28,810 >> Siamo in grado di eseguire in realtà GDB dalla riga di comando 118 00:06:28,810 --> 00:06:35,370 qui semplicemente digitando GDB e la comando che vogliamo eseguire il debug. 119 00:06:35,370 --> 00:06:37,550 In questo caso, contare. 120 00:06:37,550 --> 00:06:41,650 Ora, in questo caso, si può vedere che ci porta a un messaggio che dice GDB. 121 00:06:41,650 --> 00:06:44,020 E possiamo davvero eseguire comandi a GDB 122 00:06:44,020 --> 00:06:48,260 di iniziare effettivamente esecuzione del programma, fermati in alcuni punti, 123 00:06:48,260 --> 00:06:51,060 valutare le variabili e ispezionare le variabili che 124 00:06:51,060 --> 00:06:54,152 esistere nello stato del programma in quel momento, 125 00:06:54,152 --> 00:06:55,110 e così via. 126 00:06:55,110 --> 00:06:57,240 Esso fornisce un sacco di potenza a noi. 127 00:06:57,240 --> 00:06:59,960 >> Ma si dà il caso che l'IDE CS50 anche 128 00:06:59,960 --> 00:07:05,870 fornisce una GUI o un utente interfaccia per GDB che 129 00:07:05,870 --> 00:07:11,120 ci permette di fare questo senza bisogno l'interfaccia a riga di comando di sorta 130 00:07:11,120 --> 00:07:13,560 o addirittura a tutti. 131 00:07:13,560 --> 00:07:16,930 Il modo in cui posso accedere a tale è quello di utilizzare il pulsante di debug 132 00:07:16,930 --> 00:07:20,120 in cima dell'IDE CS50. 133 00:07:20,120 --> 00:07:24,280 Ora, in passato, quello che abbiamo visto è che usiamo il comando 134 00:07:24,280 --> 00:07:27,660 Linea per compilare ed eseguire un programma. 135 00:07:27,660 --> 00:07:29,790 >> Il pulsante di debug fa entrambi questi passaggi. 136 00:07:29,790 --> 00:07:34,380 Ma anche si apre la scheda debugger all'estrema destra 137 00:07:34,380 --> 00:07:38,280 che ci permette di ispezionare una varietà di proprietà del programma 138 00:07:38,280 --> 00:07:40,500 come è in esecuzione. 139 00:07:40,500 --> 00:07:44,280 Se clicco il debug, in questo caso, si aprirà 140 00:07:44,280 --> 00:07:48,230 una nuova scheda nella console finestra al fondo. 141 00:07:48,230 --> 00:07:51,160 >> E si può vedere che questa scheda ha alcune informazioni in cima. 142 00:07:51,160 --> 00:07:52,670 E possiamo in gran parte ignorare questo. 143 00:07:52,670 --> 00:07:54,800 Ma una delle cose che vogliamo notare 144 00:07:54,800 --> 00:07:57,170 è che emette la stessa cosa che abbiamo 145 00:07:57,170 --> 00:08:03,000 otterrebbe se abbiamo cercato di fare eseguire su il programma C nella finestra del terminale. 146 00:08:03,000 --> 00:08:06,230 >> Qui, possiamo vedere che è in esecuzione clang, e ha una varietà di bandiere, 147 00:08:06,230 --> 00:08:12,660 e di compilare il nostro file count.c, che era la scheda selezionata al momento 148 00:08:12,660 --> 00:08:15,100 che mi ha colpito di debug. 149 00:08:15,100 --> 00:08:18,010 Quindi questo è molto utile perché ora utilizzando il pulsante di debug, 150 00:08:18,010 --> 00:08:23,280 possiamo contemporaneamente compilare e poi eseguire il programma che in realtà 151 00:08:23,280 --> 00:08:24,460 desidera eseguire. 152 00:08:24,460 --> 00:08:27,880 >> Uno dei flag che è importante, in questo caso, 153 00:08:27,880 --> 00:08:30,190 abbiamo effettivamente stati utilizzando per più tempo 154 00:08:30,190 --> 00:08:32,450 ma anche appena fatto un po 'di mano agitando [incomprensibile], che 155 00:08:32,450 --> 00:08:33,820 è questo qui. 156 00:08:33,820 --> 00:08:35,790 In clang, dice -ggdb3. 157 00:08:35,790 --> 00:08:38,570 158 00:08:38,570 --> 00:08:41,250 In questo caso, ciò che siamo raccontando clang, il nostro compilatore, 159 00:08:41,250 --> 00:08:43,820 è che vogliamo compilare il nostro programma. 160 00:08:43,820 --> 00:08:46,810 Ma anche fornire quali sono chiamato informazioni sui simboli 161 00:08:46,810 --> 00:08:50,940 in modo che il compilatore ha effettivamente accesso a un sacco di informazioni di base 162 00:08:50,940 --> 00:08:52,610 contenuta all'interno del programma. 163 00:08:52,610 --> 00:08:55,260 >> Più in particolare, il numero di funzioni che ho, 164 00:08:55,260 --> 00:08:58,000 i nomi di queste funzioni, le variabili, i tipi 165 00:08:58,000 --> 00:09:01,730 che tali variabili sono, e una varietà di altre cose che aiutano il debugger 166 00:09:01,730 --> 00:09:04,350 eseguire il suo funzionamento. 167 00:09:04,350 --> 00:09:06,600 Ora c'è un'altra cosa questo è importante ricordare 168 00:09:06,600 --> 00:09:10,280 quando stiamo discutendo in esecuzione un programma in questo modo. 169 00:09:10,280 --> 00:09:13,660 >> Notare che ci sono effettivamente portato una nuova scheda nella nostra console 170 00:09:13,660 --> 00:09:14,780 lungo il fondo. 171 00:09:14,780 --> 00:09:18,600 Non abbiamo più interagire direttamente con la finestra di terminale. 172 00:09:18,600 --> 00:09:21,420 Ma questa nuova scheda è in realtà una finestra di terminale. 173 00:09:21,420 --> 00:09:26,710 È solo specifico per la gestione programma che abbiamo creato. 174 00:09:26,710 --> 00:09:29,270 >> Si noti che al fondo, in combinazione con qualche uscita 175 00:09:29,270 --> 00:09:33,500 dal clang compilatore e GDB, che possiamo in gran parte ignorano, 176 00:09:33,500 --> 00:09:37,570 in realtà mostra l'output di il nostro programma in fondo. 177 00:09:37,570 --> 00:09:41,240 Ora è importante rendersi conto che questo in realtà una finestra 178 00:09:41,240 --> 00:09:43,360 vi mostrerà il Uscita dal programma 179 00:09:43,360 --> 00:09:47,190 ma anche in grado di accettare l'input per tale programma, pure. 180 00:09:47,190 --> 00:09:49,260 >> Così nota che indica inserisci un numero, 181 00:09:49,260 --> 00:09:53,050 che è la stessa uscita che avevamo aveva nella finestra terminale prima. 182 00:09:53,050 --> 00:09:55,510 Ma è ora mostrata in questa nuova scheda. 183 00:09:55,510 --> 00:09:56,550 Posso inserire un numero. 184 00:09:56,550 --> 00:10:00,900 E sarà davvero funzione di come ci aspettiamo 185 00:10:00,900 --> 00:10:05,890 ci mostra la nostra di debug, di uscita, l'uscita che potrebbe essere bacato, 186 00:10:05,890 --> 00:10:07,010 come abbiamo visto prima. 187 00:10:07,010 --> 00:10:10,460 E in fondo, è in realtà ha un po 'di output aggiuntivo 188 00:10:10,460 --> 00:10:14,550 dal PIL solo dicendo che questo programma è stato completato. 189 00:10:14,550 --> 00:10:16,655 >> Ora, come si è visto in questo particolare corsa attraverso, 190 00:10:16,655 --> 00:10:19,370 non era particolarmente utile perché anche 191 00:10:19,370 --> 00:10:23,740 anche se abbiamo avuto il menu del debugger venire up, questo era ancora un programma in esecuzione. 192 00:10:23,740 --> 00:10:26,790 In nessun punto ha fatto in realtà sospendere l'esecuzione per noi 193 00:10:26,790 --> 00:10:30,767 per poter ispezionare tutte le variabili contenute all'interno. 194 00:10:30,767 --> 00:10:32,850 C'è un'altra cosa che dobbiamo fare per 195 00:10:32,850 --> 00:10:36,910 per arrivare GDB a riconoscere che vogliamo per sospendere l'esecuzione del programma 196 00:10:36,910 --> 00:10:42,820 e non solo permettono di procedere normalmente come si farebbe in qualsiasi altro caso. 197 00:10:42,820 --> 00:10:45,530 >> Per sospendere l'esecuzione, ad un certo linea specifica, 198 00:10:45,530 --> 00:10:47,830 abbiamo bisogno di creare ciò che è chiamato un punto di interruzione. 199 00:10:47,830 --> 00:10:52,670 E un punto di rottura è molto facilmente creati in questo CS50 IDE prendendo il mouse 200 00:10:52,670 --> 00:10:57,090 e cliccando direttamente alla sinistra da un certo numero di linea specifico. 201 00:10:57,090 --> 00:10:59,920 Una volta che lo faccio, un puntino rosso appare, che indica 202 00:10:59,920 --> 00:11:02,300 che quella linea è ormai un punto di rottura. 203 00:11:02,300 --> 00:11:07,540 >> E la prossima volta che ho eseguito GDB, è si fermerà l'esecuzione a quel punto di rottura 204 00:11:07,540 --> 00:11:10,280 quando raggiunge quella riga di codice. 205 00:11:10,280 --> 00:11:12,230 Ora, questo è un importante cosa da realizzare 206 00:11:12,230 --> 00:11:16,140 che non è necessariamente la caso che ogni riga di codice 207 00:11:16,140 --> 00:11:17,880 è in realtà accessibile. 208 00:11:17,880 --> 00:11:23,780 Se dovessi creare una funzione qui, per example-- F-- vuoto 209 00:11:23,780 --> 00:11:31,230 e basta fare una linea di stampa qui-- ciao world-- se non ho mai chiamare questa funzione, 210 00:11:31,230 --> 00:11:34,770 sarà il caso che, se ho impostato un punto di rottura qui, 211 00:11:34,770 --> 00:11:36,220 la funzione non verrà mai chiamato. 212 00:11:36,220 --> 00:11:38,310 E quindi, questo particolare punto di rottura 213 00:11:38,310 --> 00:11:43,040 non sarà mai realmente in pausa esecuzione del programma. 214 00:11:43,040 --> 00:11:48,020 >> Quindi diciamo che creo correttamente un punto di interruzione su alcuni riga di codice 215 00:11:48,020 --> 00:11:50,340 che sarà effettivamente eseguito. 216 00:11:50,340 --> 00:11:53,470 Ora, in questo caso, questo è il prima riga nella funzione principale. 217 00:11:53,470 --> 00:11:56,630 Così sarà certamente il caso che, non appena comincio esecuzione, 218 00:11:56,630 --> 00:11:58,580 la prima linea sarà raggiunto. 219 00:11:58,580 --> 00:12:00,230 GDB si sospendere l'esecuzione. 220 00:12:00,230 --> 00:12:04,100 E poi, sarò in grado di interagire con il debugger. 221 00:12:04,100 --> 00:12:08,480 >> È possibile impostare linee multiple come punti di interruzione, se si desidera. 222 00:12:08,480 --> 00:12:11,365 Possiamo anche creare una line up qui in questo segmento di codice 223 00:12:11,365 --> 00:12:12,490 che non verrà mai raggiunto. 224 00:12:12,490 --> 00:12:14,744 E possiamo anche impostare un ulteriore seguito. 225 00:12:14,744 --> 00:12:16,660 Il motivo per cui ci sarebbe vuole fare questo faremo 226 00:12:16,660 --> 00:12:19,119 andare in un po 'di più dettaglio in un attimo. 227 00:12:19,119 --> 00:12:21,660 Quindi per ora, vorrei solo disattivare questi punti di interruzione aggiuntivi 228 00:12:21,660 --> 00:12:24,940 in modo che possiamo guardare a quello che succede quando ho una sola pausa 229 00:12:24,940 --> 00:12:27,650 punto nel mio programma. 230 00:12:27,650 --> 00:12:29,410 Ho fatto un po ' modifiche a questo programma. 231 00:12:29,410 --> 00:12:30,750 Quindi ho bisogno di salvarlo. 232 00:12:30,750 --> 00:12:34,490 Farò clic di debug in modo che possa iniziare la compilazione e poi 233 00:12:34,490 --> 00:12:36,880 esecuzione del debugger. 234 00:12:36,880 --> 00:12:40,632 >> Vedremo che, dopo i momenti, i linea che abbiamo scelto come la rottura 235 00:12:40,632 --> 00:12:43,360 punto è evidenziato in giallo. 236 00:12:43,360 --> 00:12:47,440 Possiamo anche notare che nel superiore destro del pannello di debug 237 00:12:47,440 --> 00:12:50,940 che l'icona di pausa si è trasformata in un piccola icona di gioco. 238 00:12:50,940 --> 00:12:54,710 Ciò significa che abbiamo la pausa esecuzione, in questo caso particolare. 239 00:12:54,710 --> 00:12:57,840 E premendo il pulsante Play sarebbe ci permettono di riprendere l'esecuzione 240 00:12:57,840 --> 00:13:00,000 a quel punto specifico. 241 00:13:00,000 --> 00:13:03,240 >> Si noti che ci sono un paio di altri pulsanti disponibili in questo pannello di debug, 242 00:13:03,240 --> 00:13:04,220 anche. 243 00:13:04,220 --> 00:13:09,470 Scavalcare, che mi permette di eseguire tale una riga di codice 244 00:13:09,470 --> 00:13:14,030 e passo verso quella linea al successiva, che, in questo caso, 245 00:13:14,030 --> 00:13:17,060 significherebbe che il printf istruzione viene eseguita. 246 00:13:17,060 --> 00:13:22,310 E sarà poi una pausa esecuzione sulla linea 13, in questo modo. 247 00:13:22,310 --> 00:13:25,090 >> E c'è anche un passo in funzione, che 248 00:13:25,090 --> 00:13:28,950 è utile se ho creato altri funzioni in altre parti del codice sorgente. 249 00:13:28,950 --> 00:13:31,420 E voglio entrare in quelle funzioni, piuttosto che 250 00:13:31,420 --> 00:13:33,050 eseguire tale funzione nel suo complesso. 251 00:13:33,050 --> 00:13:37,279 Ma vedremo più al passo in funzione in un attimo. 252 00:13:37,279 --> 00:13:40,320 Ora notate alcune altre cose che in realtà esistere all'interno di questo pannello di debug. 253 00:13:40,320 --> 00:13:44,110 >> Abbiamo questo pannello chiamato Stack di chiamate, che ci mostra 254 00:13:44,110 --> 00:13:45,300 dove esattamente siamo. 255 00:13:45,300 --> 00:13:48,550 In questo caso, siamo dentro della funzione principale. 256 00:13:48,550 --> 00:13:50,880 Il nostro script si chiama count.c. 257 00:13:50,880 --> 00:13:53,820 E ci capita di essere su linea 13, prima colonna, che 258 00:13:53,820 --> 00:13:58,950 è esattamente ciò che la regione evidenziata del codice sorgente indica, pure. 259 00:13:58,950 --> 00:14:02,435 >> Ora si noti che questo dimostra anche nella sezione variabile locale 260 00:14:02,435 --> 00:14:06,710 tutte le variabili che esistere all'interno di questa funzione. 261 00:14:06,710 --> 00:14:08,930 E 'importante notare che tutte le variabili 262 00:14:08,930 --> 00:14:12,580 appariranno in questa variabile locale sezione all'interno di una funzione, 263 00:14:12,580 --> 00:14:14,380 ancor prima che siano definite. 264 00:14:14,380 --> 00:14:19,160 Possiamo vedere qui che abbiamo una variabile chiamato num, ha un valore di default di 0, 265 00:14:19,160 --> 00:14:21,280 ed è di tipo int. 266 00:14:21,280 --> 00:14:24,110 >> Ora, prima abbiamo effettivamente inizializzare tutte queste variabili, 267 00:14:24,110 --> 00:14:26,685 non siamo necessariamente garantito a vedere il valore 0. 268 00:14:26,685 --> 00:14:29,200 E a seconda di altre esecuzioni che sia stata eseguita 269 00:14:29,200 --> 00:14:32,020 e lo stato della vostra memoria quando in realtà esegue questo programma, 270 00:14:32,020 --> 00:14:34,605 si potrebbe scoprire che si non vedono valori di 0 271 00:14:34,605 --> 00:14:36,550 e, invece, alcuni altri numeri folli. 272 00:14:36,550 --> 00:14:38,390 >> Ma non ti preoccupare di questo. 273 00:14:38,390 --> 00:14:44,610 Non sarà rilevante fino effettivamente inizializzare il valore. 274 00:14:44,610 --> 00:14:49,630 Ora, in questo caso, possiamo vedere che Ho effettuato alcune uscite. 275 00:14:49,630 --> 00:14:52,131 E sto, in questo momento, una pausa di esecuzione. 276 00:14:52,131 --> 00:14:53,880 Ma in questo caso, ciò che Ho molta voglia di fare 277 00:14:53,880 --> 00:14:58,060 è per ora un passo su questa linea di codice in modo che io possa realmente 278 00:14:58,060 --> 00:15:04,390 chiedere all'utente che int che vogliamo usare nel nostro programma. 279 00:15:04,390 --> 00:15:07,060 >> Ora, in questo caso, quando Mi ha colpito scavalcare, avviso 280 00:15:07,060 --> 00:15:11,940 che la pausa, o meglio il Resume tasto è cambiato a questo pulsante Pausa 281 00:15:11,940 --> 00:15:14,022 perché questo codice è effettivamente in esecuzione. 282 00:15:14,022 --> 00:15:15,730 Che cosa sta succedendo in questo momento è che si tratta 283 00:15:15,730 --> 00:15:21,630 ci aspetta di inserire i dati come possiamo vedere dal nostro testo di output 284 00:15:21,630 --> 00:15:23,600 al fondo. 285 00:15:23,600 --> 00:15:25,787 >> Così adesso, questo è in realtà non in pausa, 286 00:15:25,787 --> 00:15:28,620 anche se, una sorta di, appare di essere, perché non succede niente. 287 00:15:28,620 --> 00:15:32,360 Ma si dà il caso che, in il mio caso specifico sulla linea 13, 288 00:15:32,360 --> 00:15:34,210 Sto aspettando l'input dell'utente. 289 00:15:34,210 --> 00:15:39,130 E così GDB non è in grado di ispezionare un programma è in esecuzione. 290 00:15:39,130 --> 00:15:43,370 >> Ora la prossima volta che entro in un po ' input-- quindi mi inserisco quel numero 5, 291 00:15:43,370 --> 00:15:46,140 come abbiamo visto nella past-- premere Invio, e noi 292 00:15:46,140 --> 00:15:51,430 notare che, immediatamente, pause GDB e, ancora una volta, mette in evidenza la riga successiva. 293 00:15:51,430 --> 00:15:55,320 Ma si noti che ora, come un risultato della nostra introduzione di un valore, 294 00:15:55,320 --> 00:15:58,930 abbiamo aggiornato il valore interno delle nostre variabili locali, che 295 00:15:58,930 --> 00:16:05,560 è molto utile per sapere con precisione cosa che numero era in memoria. 296 00:16:05,560 --> 00:16:10,650 >> Ora posso permettere che questo programma di continuare giocare fino alla fine della sua esecuzione 297 00:16:10,650 --> 00:16:12,570 colpendo Riprendi. 298 00:16:12,570 --> 00:16:16,410 Possiamo vedere che molto rapidamente fa la finitura programma in esecuzione 299 00:16:16,410 --> 00:16:19,790 con la stessa uscita che avuto prima, il debugger si chiude, 300 00:16:19,790 --> 00:16:23,170 e ora questo programma si è fermato completamente. 301 00:16:23,170 --> 00:16:25,320 >> Mostro che solo per il Ai fini di vedere cosa 302 00:16:25,320 --> 00:16:27,280 succede quando abbiamo effettivamente colpito Riprendi. 303 00:16:27,280 --> 00:16:30,640 Ma in realtà stiamo per voglia di tornare in questo programma 304 00:16:30,640 --> 00:16:33,820 in modo da poter cercare di eseguire il debug esattamente ciò che sta accadendo. 305 00:16:33,820 --> 00:16:37,980 Ora che sto utilizzando il debugger, posso non hanno bisogno di queste dichiarazioni di debug printf. 306 00:16:37,980 --> 00:16:43,860 >> Così ho potuto rimuoverli come farò ora solo per tornare al nostro codice più semplice 307 00:16:43,860 --> 00:16:45,950 che abbiamo avuto un momento fa. 308 00:16:45,950 --> 00:16:48,790 Ora, quando salvo la programmare ed eseguirlo, 309 00:16:48,790 --> 00:16:53,700 sarà, ancora una volta, andare a quella iniziale punto che ho avuto sulla linea 11 rompere. 310 00:16:53,700 --> 00:16:57,700 E sarò in grado di ispezionare le mie variabili voglio fare. 311 00:16:57,700 --> 00:17:00,695 >> Si dà il caso che questo parte non è molto interessante, 312 00:17:00,695 --> 00:17:04,364 E so che sto andando stampare questa dichiarazione. 313 00:17:04,364 --> 00:17:05,280 Si prega di inserire un numero. 314 00:17:05,280 --> 00:17:08,099 E poi, so che sto andando chiedere all'utente per quella intero. 315 00:17:08,099 --> 00:17:13,329 Quindi, forse, io in realtà voglio spostare la mia punto rompere un po 'più in basso. 316 00:17:13,329 --> 00:17:16,710 >> È possibile rimuovere punti di interruzione cliccando, ancora una volta, direttamente 317 00:17:16,710 --> 00:17:18,460 a fianco di tale numero di riga. 318 00:17:18,460 --> 00:17:22,200 Quel punto rosso scompare, a indicare che quel punto di rottura è ormai andato. 319 00:17:22,200 --> 00:17:24,780 Ora, in questo caso, esecuzione è stata sospesa. 320 00:17:24,780 --> 00:17:27,770 E quindi non è in realtà sta per riprendere in quel caso particolare. 321 00:17:27,770 --> 00:17:30,210 Ma posso impostare una pausa puntare un po 'più tardi. 322 00:17:30,210 --> 00:17:33,880 >> E quando mi riprendo la mia ora codice, riprenderà e raccontare 323 00:17:33,880 --> 00:17:36,190 il punto di che punto di rottura. 324 00:17:36,190 --> 00:17:37,374 Ancora una volta, mi ha colpito Riprendi. 325 00:17:37,374 --> 00:17:39,040 Non sembra nulla sta accadendo. 326 00:17:39,040 --> 00:17:41,450 Ma questo è perché il mio codice è in attesa di input. 327 00:17:41,450 --> 00:17:47,900 Io entrerò un numero 5, premere Invio, e ora il prossimo punto di interruzione sarà colpito. 328 00:17:47,900 --> 00:17:50,570 >> Ora, in questo caso, questo è la linea di codice 329 00:17:50,570 --> 00:17:53,820 che, prima, sapevamo è capitato di essere buggy. 330 00:17:53,820 --> 00:17:57,590 Quindi cerchiamo di valutare ciò che accade in questo particolare momento. 331 00:17:57,590 --> 00:18:02,620 Quando una riga viene evidenziata, questo linea non è ancora stata eseguita. 332 00:18:02,620 --> 00:18:06,490 Quindi, in questo caso, possiamo vedere che ho un numero, che 333 00:18:06,490 --> 00:18:11,610 Ho un intero chiamato num che ha un valore 5. 334 00:18:11,610 --> 00:18:15,090 E ho intenzione di essere l'esecuzione po 'di matematica su quel numero. 335 00:18:15,090 --> 00:18:20,130 >> Se faccio un passo su quella, possiamo notare che il valore per i num 336 00:18:20,130 --> 00:18:23,780 è cambiato secondo la aritmetica che abbiamo effettivamente fatto. 337 00:18:23,780 --> 00:18:26,810 E ora che siamo all'interno di questo ciclo for 338 00:18:26,810 --> 00:18:29,090 o adesso che il ciclo for si è evidenziato, 339 00:18:29,090 --> 00:18:32,450 vediamo che abbiamo un nuovo variabile i chiamati che 340 00:18:32,450 --> 00:18:35,370 sta per essere utilizzato in tale ciclo for. 341 00:18:35,370 --> 00:18:38,230 >> Ora ricordate prima che io ha detto che a volte sei 342 00:18:38,230 --> 00:18:43,470 andando a vedere un qualche tipo di folle numeri come predefinito prima che il numero 343 00:18:43,470 --> 00:18:45,530 o che variabile è realmente inizializzato. 344 00:18:45,530 --> 00:18:49,040 Possiamo vedere che proprio qui in questa variabile 345 00:18:49,040 --> 00:18:51,345 chiamato i, che non ha ancora stato inizializzato 346 00:18:51,345 --> 00:18:53,560 al momento di evidenziare. 347 00:18:53,560 --> 00:18:57,070 Ma possiamo vedere che ha qualche numero che non avremmo fatto aspettare. 348 00:18:57,070 --> 00:18:57,620 >> Va bene. 349 00:18:57,620 --> 00:18:59,661 Non ti preoccupare perché non abbiamo in realtà 350 00:18:59,661 --> 00:19:04,970 inizializzato tale numero fino a quando ho passo su questa linea, il valore 351 00:19:04,970 --> 00:19:08,560 i è stato inizializzato al valore 1. 352 00:19:08,560 --> 00:19:11,400 Quindi, per vedere che che in realtà il caso, facciamo un passo sopra. 353 00:19:11,400 --> 00:19:14,420 Ora possiamo vedere che quella linea è stata eseguita. 354 00:19:14,420 --> 00:19:17,000 Ed ora stiamo evidenziando questa linea printf. 355 00:19:17,000 --> 00:19:22,230 >> Ed ora possiamo vedere come i nostri valori di I e 3 sono cambiate nel tempo. 356 00:19:22,230 --> 00:19:26,450 Ciò è molto utile per fare, infatti, è quello di scavalcare le linee più volte. 357 00:19:26,450 --> 00:19:30,480 E si può trovare ciò che realmente accade all'interno del vostro ciclo for 358 00:19:30,480 --> 00:19:33,660 e cosa accade al variabili all'interno di quel ciclo for 359 00:19:33,660 --> 00:19:39,200 come che l'esecuzione del programma si verifica un passo alla volta. 360 00:19:39,200 --> 00:19:41,110 >> Ora, a questo punto, io scavalcato appena sufficiente 361 00:19:41,110 --> 00:19:44,210 che ora sono alla fine del mio programma. 362 00:19:44,210 --> 00:19:46,980 Se faccio un passo oltre che, lo farà in realtà cessare esecuzione 363 00:19:46,980 --> 00:19:48,860 come abbiamo visto in passato. 364 00:19:48,860 --> 00:19:52,110 Permettetemi di riavviare questo, ancora una volta, in modo da che posso indicare qualcos'altro fuori, 365 00:19:52,110 --> 00:19:53,320 anche. 366 00:19:53,320 --> 00:19:55,350 >> In questo caso, è ora mi chiede, ancora una volta, 367 00:19:55,350 --> 00:19:57,100 per un numero, che Io, di nuovo, entrare. 368 00:19:57,100 --> 00:20:00,300 Ma questa volta, ho intenzione di entrare in un numero più grande in modo che il ciclo for 369 00:20:00,300 --> 00:20:02,540 sarà iterare più volte. 370 00:20:02,540 --> 00:20:06,090 In questo caso, ho intenzione per immettere un valore di 11. 371 00:20:06,090 --> 00:20:08,390 >> Ora di nuovo perché avevo impostato un punto di interruzione alla linea 15, 372 00:20:08,390 --> 00:20:10,490 sta andando a evidenziare quella linea. 373 00:20:10,490 --> 00:20:12,980 Possiamo vedere che il nostro numero 11 è correttamente 374 00:20:12,980 --> 00:20:15,560 rappresentata nelle nostre variabili locali. 375 00:20:15,560 --> 00:20:22,460 Scavalcando che, possiamo ora vedere cosa succede al nostro valore di i 376 00:20:22,460 --> 00:20:25,680 come si procede all'interno di questo per ciclo. 377 00:20:25,680 --> 00:20:31,960 Esso viene incrementato ogni volta che raggiungere la cima di quella per ciclo. 378 00:20:31,960 --> 00:20:35,110 >> Ora, una delle cose che potrebbero essere utile per fare durante l'esecuzione 379 00:20:35,110 --> 00:20:40,490 di questo programma è per me realmente cambiare le variabili midstream per vedere 380 00:20:40,490 --> 00:20:42,450 cosa accade al mio programma. 381 00:20:42,450 --> 00:20:46,540 In questo caso, posso effettivamente doppio clic sul valore. 382 00:20:46,540 --> 00:20:48,040 Notare che diventa un campo di testo. 383 00:20:48,040 --> 00:20:50,280 >> Ora posso entrare diverso valorizzare tutto 384 00:20:50,280 --> 00:20:55,700 per vedere come si comporta il mio programma quando ho cambiato quella variabile. 385 00:20:55,700 --> 00:20:59,560 Ora, in questo caso, la variabile Io ora contiene il valore 10. 386 00:20:59,560 --> 00:21:02,810 Ma il programma è ancora pausa in esecuzione. 387 00:21:02,810 --> 00:21:07,610 Quando faccio un passo oltre, vedo che il valore i, che sono entrato come 10, 388 00:21:07,610 --> 00:21:12,170 non è maggiore del valore di num, che provoca subito il ciclo for 389 00:21:12,170 --> 00:21:14,240 per fermare l'esecuzione. 390 00:21:14,240 --> 00:21:16,210 >> Ora che non è l'unico motivo per cui si farebbe 391 00:21:16,210 --> 00:21:19,450 voler modificare la variabile in luogo. 392 00:21:19,450 --> 00:21:22,210 Oppure potresti tentare di modificarlo così 393 00:21:22,210 --> 00:21:24,590 che si può continuare esecuzione di un ciclo 394 00:21:24,590 --> 00:21:27,370 oppure in modo che è possibile modificare un valore prima che 395 00:21:27,370 --> 00:21:32,630 raggiunge un insieme specifico di aritmetica che si sta per eseguire. 396 00:21:32,630 --> 00:21:36,210 >> Quindi, ora che abbiamo effettivamente cambiare il valore di i come il programma era in esecuzione, 397 00:21:36,210 --> 00:21:39,540 ha causato il ciclo for per uscire prematuramente a causa, tutto ad un tratto, i 398 00:21:39,540 --> 00:21:42,770 successo di essere maggiore del valore di num, il che significa che quella per il ciclo 399 00:21:42,770 --> 00:21:45,410 non è più necessario da eseguire. 400 00:21:45,410 --> 00:21:48,780 Inoltre, è successo di essere il caso che abbiamo cambiato il valore di i 401 00:21:48,780 --> 00:21:53,270 quando la linea 17 è stata evidenziata, che era il punto nel tempo 402 00:21:53,270 --> 00:21:56,280 che il ciclo di esecuzione era in realtà in corso di valutazione. 403 00:21:56,280 --> 00:22:00,210 >> Se avessi cambiato il valore di i su una linea diversa, dico 19, 404 00:22:00,210 --> 00:22:03,360 avremmo visto diverso comportamento perché la linea 19 sarebbe 405 00:22:03,360 --> 00:22:08,310 hanno eseguito prima del ciclo condizione è stata rivalutata. 406 00:22:08,310 --> 00:22:11,900 Ora, a questo punto, sono, ancora una volta, alla fine di questo programma. 407 00:22:11,900 --> 00:22:15,707 E posso permettere che questo procedere alla consentire il mio programma per uscire in modo naturale. 408 00:22:15,707 --> 00:22:18,290 Ma ci sono un paio di cose che sono importanti per portare via 409 00:22:18,290 --> 00:22:19,960 da questa particolare discussione. 410 00:22:19,960 --> 00:22:22,490 È necessario valutare le proprie ipotesi 411 00:22:22,490 --> 00:22:24,710 su come il codice deve essere comportarsi. 412 00:22:24,710 --> 00:22:28,220 Ogni volta che si pensa che qualche pezzo di codice si sa capita di lavorare, 413 00:22:28,220 --> 00:22:30,940 che potrebbe essere una bandiera rossa per andare indietro e valutare, ed essere sicuri 414 00:22:30,940 --> 00:22:33,470 che la vostra assunzione di come quel codice è in funzione 415 00:22:33,470 --> 00:22:38,290 in realtà è vero per come è espressi nel codice sorgente. 416 00:22:38,290 --> 00:22:41,300 >> Ma ancora più a punto è stato, quando stiamo usando il debugger, 417 00:22:41,300 --> 00:22:43,920 si può mettere i punti di interruzione a diverse linee di codice, 418 00:22:43,920 --> 00:22:48,110 che farà sì che il debugger sospendere l'esecuzione in ciascuna di queste linee 419 00:22:48,110 --> 00:22:52,210 in modo da poter valutare la memoria o addirittura cambiare in posizione. 420 00:22:52,210 --> 00:22:55,630 E ancora una volta, ricordate che è possibile creare più punti di interruzione in modo che si 421 00:22:55,630 --> 00:23:00,390 possono anche riprendere l'esecuzione, saltare su ampie porzioni di codice, 422 00:23:00,390 --> 00:23:04,790 e sarà in pausa automaticamente al successivo punto di interruzione. 423 00:23:04,790 --> 00:23:07,760 >> Ci sono in realtà più avanzate caratteristiche del debugger, pure. 424 00:23:07,760 --> 00:23:10,170 Ma dovremo fare riferimento per alcuni video successive 425 00:23:10,170 --> 00:23:14,090 al fine di prendere in giro davvero a parte come utilizzare tali funzioni particolari. 426 00:23:14,090 --> 00:23:15,990 Per ora, grazie molto per la visione. 427 00:23:15,990 --> 00:23:18,080 E buona fortuna debug.