1 00:00:00,000 --> 00:00:00,309 2 00:00:00,309 --> 00:00:02,350 [? DAN ARMADARAS:?] Hi, Eu sou [? Dan Armadaras?]. 3 00:00:02,350 --> 00:00:04,410 Hoje, nós estamos indo para estar a olhar para a depuração. 4 00:00:04,410 --> 00:00:06,697 Não só estamos indo para falar sobre algumas técnicas, 5 00:00:06,697 --> 00:00:09,280 mas também vamos olhar para algumas das funcionalidades contidas 6 00:00:09,280 --> 00:00:14,170 dentro do IDE CS50 que permitem você depurar facilmente um programa. 7 00:00:14,170 --> 00:00:16,272 >> Apenas um exemplo de algo que pode dar errado 8 00:00:16,272 --> 00:00:18,730 e é realmente algo que já vimos antes. 9 00:00:18,730 --> 00:00:23,200 Neste caso, este é um programa C que aceita um número inteiro a partir do utilizador, 10 00:00:23,200 --> 00:00:27,580 divide por dois, e fornece a saída de volta para o usuário. 11 00:00:27,580 --> 00:00:30,610 Agora, a partir do que vimos anteriormente em palestras, 12 00:00:30,610 --> 00:00:34,370 sabemos que isso vai realmente causar tipos específicos de problemas de divisão 13 00:00:34,370 --> 00:00:35,860 quando temos números ímpares. 14 00:00:35,860 --> 00:00:40,330 >> Especificamente, nós vamos simplesmente jogar fora qualquer coisa depois do ponto decimal. 15 00:00:40,330 --> 00:00:43,170 Agora, nós sabemos que este passa a ser o caso. 16 00:00:43,170 --> 00:00:47,430 E se nós executá-lo, podemos confirmar nossas suspeitas, primeiro, compilando. 17 00:00:47,430 --> 00:00:50,460 E, em seguida, executando e inserindo um número ímpar. 18 00:00:50,460 --> 00:00:51,720 >> Isso não é novidade. 19 00:00:51,720 --> 00:00:54,490 Mas este é realmente um exemplo de um erro que 20 00:00:54,490 --> 00:00:58,810 pode existir dentro de um programa maior que se torna mais difícil de rastrear. 21 00:00:58,810 --> 00:01:02,640 Apesar de sabermos qual é o problema é, o verdadeiro cerne da questão 22 00:01:02,640 --> 00:01:06,250 pode estar tentando identificar especificamente onde o erro ocorre, 23 00:01:06,250 --> 00:01:09,750 identificar o que esse problema é, em seguida, fixando-o. 24 00:01:09,750 --> 00:01:14,400 Por isso, fornecer isso como um exemplo do que poderia ser algo 25 00:01:14,400 --> 00:01:19,030 que já sabemos, mas pode ser enterrado dentro de outros elementos do código. 26 00:01:19,030 --> 00:01:23,090 >> Assim, abrindo esta outra fonte arquivo de código como um exemplo, 27 00:01:23,090 --> 00:01:27,165 este problema de divisão é agora parte de um programa maior. 28 00:01:27,165 --> 00:01:29,040 Ainda pode ser um pouco pouco artificial, e nós 29 00:01:29,040 --> 00:01:31,076 pode ser capaz de facilmente identificá-lo, especialmente 30 00:01:31,076 --> 00:01:32,450 uma vez que estamos apenas discutindo isso. 31 00:01:32,450 --> 00:01:38,250 Mas podemos descobrir que esta problema pode existir em uma escala maior. 32 00:01:38,250 --> 00:01:45,450 >> Se eu compilar isso e agora executá-lo, digite um número ímpar, 33 00:01:45,450 --> 00:01:49,816 podemos ver que nós não conseguimos precisamente a saída que nós podemos ter esperado. 34 00:01:49,816 --> 00:01:51,690 Neste caso particular, poderíamos dizer que nós 35 00:01:51,690 --> 00:01:56,060 deseja contar todos os números de um a um número específico. 36 00:01:56,060 --> 00:01:58,130 E podemos ver que nós tem uma variedade de questões 37 00:01:58,130 --> 00:02:03,880 aqui se estiver saída, simplesmente, 0 e 1, quando nós fornecemos uma entrada de 5. 38 00:02:03,880 --> 00:02:07,380 >> Então, nós já sabemos que há um problema aqui. 39 00:02:07,380 --> 00:02:11,662 Mas nós não podemos saber com precisão onde este problema realmente existe. 40 00:02:11,662 --> 00:02:13,620 Agora, uma das maneiras que podemos tentar corrigir isso 41 00:02:13,620 --> 00:02:15,745 é algo que nós temos já foram introduzidas para. 42 00:02:15,745 --> 00:02:18,880 Nós podemos apenas usá-lo em uma escala maior. 43 00:02:18,880 --> 00:02:21,680 >> Na linha 14, temos esta função printf, 44 00:02:21,680 --> 00:02:25,620 o que nos permite imprimir o estado de várias peças de informação. 45 00:02:25,620 --> 00:02:28,880 E isso é algo que você deve alavancar dentro de seu programa 46 00:02:28,880 --> 00:02:33,100 para tentar descobrir exatamente o que é acontecendo em várias linhas de código. 47 00:02:33,100 --> 00:02:36,350 Assim, mesmo que este não é o resultado final que, na verdade, 48 00:02:36,350 --> 00:02:39,830 quer produzir fora do Neste programa, nós ainda 49 00:02:39,830 --> 00:02:42,300 pode ter alguma depuração declarações onde nós 50 00:02:42,300 --> 00:02:46,970 pode tentar descobrir exatamente o que está acontecendo dentro do nosso código. 51 00:02:46,970 --> 00:02:51,210 >> Portanto, neste caso, eu vou printf com o tag de depuração. 52 00:02:51,210 --> 00:02:53,540 Neste caso, esta é apenas uma seqüência de depuração 53 00:02:53,540 --> 00:02:56,840 que eu estou colocando-se para que se torne muito claro na saída do meu código 54 00:02:56,840 --> 00:02:59,200 o que é que eu quero mostrar. 55 00:02:59,200 --> 00:03:04,410 E aqui o número de saída que temos calculado. 56 00:03:04,410 --> 00:03:06,800 >> Neste caso, eu poderia quero saber exatamente 57 00:03:06,800 --> 00:03:11,380 o que está acontecendo antes e depois de alguns cálculos específicos. 58 00:03:11,380 --> 00:03:16,224 Então eu poderia usar um printf antes e depois de que a linha de código. 59 00:03:16,224 --> 00:03:18,640 Neste caso, eu poderia até mesmo torná-lo um pouco mais clara 60 00:03:18,640 --> 00:03:21,960 dizendo depuração antes e depuração depois de tanto 61 00:03:21,960 --> 00:03:26,540 que eu não confundir-me com várias linhas que parecem idênticas. 62 00:03:26,540 --> 00:03:32,290 >> Agora, se nós recompilar este e correr -lo, digite um número como cinco de novo, 63 00:03:32,290 --> 00:03:35,090 podemos ver que temos Agora saída antes e depois 64 00:03:35,090 --> 00:03:40,670 e achar que não temos feito uma clara divisão ou ter claro do número 65 00:03:40,670 --> 00:03:43,680 que nós realmente queremos fazer. 66 00:03:43,680 --> 00:03:48,660 Agora, neste caso, esta é não é realmente uma saída clara. 67 00:03:48,660 --> 00:03:52,440 Não é realmente um resultado claro que nós queremos fora deste programa particular. 68 00:03:52,440 --> 00:03:54,427 >> E isto é, novamente, uma pouco artificial. 69 00:03:54,427 --> 00:03:57,510 Mas, talvez, uma das coisas que nós poderíamos fazer se a especificação disse 70 00:03:57,510 --> 00:04:01,900 que queremos dividir isso por 2 e adicionar 1-- Assim, em outras palavras, 71 00:04:01,900 --> 00:04:04,550 queremos arredondar up-- seguida podemos saber que pudéssemos 72 00:04:04,550 --> 00:04:08,060 fazer essa coisa particular, neste caso. 73 00:04:08,060 --> 00:04:14,010 Agora aqui nós sabemos que seremos capaz de adicionar 1 para o nosso número para metade. 74 00:04:14,010 --> 00:04:16,490 >> Vamos recompilar este e confirmar que esta 75 00:04:16,490 --> 00:04:18,860 está se comportando da maneira que queremos. 76 00:04:18,860 --> 00:04:21,980 Podemos ver que agora antes tendo, temos o número 5. 77 00:04:21,980 --> 00:04:26,620 Depois de ter, que tem o número 3, que de acordo com nossa especificação, 78 00:04:26,620 --> 00:04:29,292 é o que queríamos fazer. 79 00:04:29,292 --> 00:04:31,000 Mas se olharmos para o saída aqui, nós podemos 80 00:04:31,000 --> 00:04:33,760 ver que poderíamos ter outro Preenchimento completo, que é 81 00:04:33,760 --> 00:04:36,940 que estamos começando a contagem a partir de 0. 82 00:04:36,940 --> 00:04:39,390 >> Agora, novamente, isso é algo que vimos no passado 83 00:04:39,390 --> 00:04:42,500 e que possamos corrigi muito facilmente. 84 00:04:42,500 --> 00:04:44,790 Mas, neste caso, nós também tinha o benefício 85 00:04:44,790 --> 00:04:48,940 de usar a instrução printf diretamente dentro do loop for 86 00:04:48,940 --> 00:04:52,930 para saber exatamente onde que o erro estava ocorrendo. 87 00:04:52,930 --> 00:04:55,150 Então, são declarações printf muito útil para ajudar 88 00:04:55,150 --> 00:04:57,940 a determinar onde, precisamente em seu código-fonte, 89 00:04:57,940 --> 00:05:00,620 um erro específico está ocorrendo. 90 00:05:00,620 --> 00:05:03,650 >> E é também importante perceber que, como estamos escrevendo código, 91 00:05:03,650 --> 00:05:06,052 nós poderíamos ter premissas sobre o estado de um programa. 92 00:05:06,052 --> 00:05:08,510 Ou talvez tenhamos premissas sobre o que parte do programa 93 00:05:08,510 --> 00:05:13,020 é realmente correto ou incorreto quando mais tarde, à medida que construímos sobre esse programa 94 00:05:13,020 --> 00:05:15,950 e torná-lo parte de uma complexo e programa maior 95 00:05:15,950 --> 00:05:19,700 que nos damos conta de que algum aspecto de que é realmente buggy. 96 00:05:19,700 --> 00:05:22,680 >> Usando printf pode realmente ajudar diminuir e identificar 97 00:05:22,680 --> 00:05:26,430 As regiões de um programa que não pode estar se comportando exatamente da maneira que nós 98 00:05:26,430 --> 00:05:29,500 esperar, com base em nossas suposições. 99 00:05:29,500 --> 00:05:31,460 Mas há outras ferramentas disponível, bem como, 100 00:05:31,460 --> 00:05:34,860 que nos permitem tentar figura para fora onde está ocorrendo um erro 101 00:05:34,860 --> 00:05:39,930 e também, especificamente, o que as coisas estão acontecendo dentro do programa. 102 00:05:39,930 --> 00:05:41,990 >> Então, usando printf é muito quando queremos útil 103 00:05:41,990 --> 00:05:45,900 para identificar áreas específicas de um programa que tem algum bug. 104 00:05:45,900 --> 00:05:47,730 Mas também se torna tedioso depois de um tempo. 105 00:05:47,730 --> 00:05:50,500 Neste caso, este é um programa relativamente simples 106 00:05:50,500 --> 00:05:52,750 com apenas uma ou duas variáveis. 107 00:05:52,750 --> 00:05:57,260 E torna-se muito fácil para nós imprimir o valor dessas variáveis 108 00:05:57,260 --> 00:05:59,670 no contexto do programa maior. 109 00:05:59,670 --> 00:06:02,670 >> Mas podemos ter um diferente programa que tem muitas variáveis. 110 00:06:02,670 --> 00:06:06,530 E isso não pode ser completamente tão fácil de usar printf 111 00:06:06,530 --> 00:06:10,120 para tentar avaliar o que está acontecendo para cada uma dessas variáveis 112 00:06:10,120 --> 00:06:13,590 como o programa está em execução. 113 00:06:13,590 --> 00:06:16,960 Há um programa que existe chamado um programa depurador. 114 00:06:16,960 --> 00:06:20,320 Neste caso, a que iremos uso é o depurador GNU, ou GDB, 115 00:06:20,320 --> 00:06:24,260 que nos permite inspecionar o interno funcionamento de um programa em um muito mais 116 00:06:24,260 --> 00:06:25,700 forma detalhada. 117 00:06:25,700 --> 00:06:28,810 >> Nós podemos realmente executar GDB da linha de comando 118 00:06:28,810 --> 00:06:35,370 aqui simplesmente digitando GDB eo comando que deseja depurar. 119 00:06:35,370 --> 00:06:37,550 Neste caso, contam. 120 00:06:37,550 --> 00:06:41,650 Agora, neste caso, podemos ver que ele nos leva a um prompt que diz GDB. 121 00:06:41,650 --> 00:06:44,020 E nós podemos, na verdade, executar comandos para GDB 122 00:06:44,020 --> 00:06:48,260 para efectivamente iniciar a execução do programa, pará-lo em certos pontos, 123 00:06:48,260 --> 00:06:51,060 avaliar as variáveis ​​e inspecionar as variáveis ​​que 124 00:06:51,060 --> 00:06:54,152 existe no estado de programa naquele momento em particular, 125 00:06:54,152 --> 00:06:55,110 e assim por diante. 126 00:06:55,110 --> 00:06:57,240 Ele fornece uma grande quantidade de energia para nós. 127 00:06:57,240 --> 00:06:59,960 >> Mas isso só acontece que o IDE também CS50 128 00:06:59,960 --> 00:07:05,870 fornece uma interface gráfica ou um usuário interface para que o GDB 129 00:07:05,870 --> 00:07:11,120 nos permite fazer isso sem a necessidade de a interface de linha de comando que seja 130 00:07:11,120 --> 00:07:13,560 ou em tudo mesmo. 131 00:07:13,560 --> 00:07:16,930 A maneira que eu possa acessar esse é usando o botão de debug 132 00:07:16,930 --> 00:07:20,120 no topo do IDE CS50. 133 00:07:20,120 --> 00:07:24,280 Agora, no passado, o que nós temos visto é que nós usamos o comando 134 00:07:24,280 --> 00:07:27,660 linha para compilar e, em seguida, executar um programa. 135 00:07:27,660 --> 00:07:29,790 >> O botão de debug faz ambos os passos. 136 00:07:29,790 --> 00:07:34,380 Mas também vai trazer o guia depurador na extrema direita 137 00:07:34,380 --> 00:07:38,280 que nos permite inspecionar uma variedade de propriedades do programa 138 00:07:38,280 --> 00:07:40,500 como ele está sendo executado. 139 00:07:40,500 --> 00:07:44,280 Se eu clicar debug, neste caso, ele trará 140 00:07:44,280 --> 00:07:48,230 uma nova guia no console janela na parte inferior. 141 00:07:48,230 --> 00:07:51,160 >> E você pode ver que este guia tem algumas informações no topo. 142 00:07:51,160 --> 00:07:52,670 E podemos, em grande parte ignorar isso. 143 00:07:52,670 --> 00:07:54,800 Mas uma das coisas que queremos notar 144 00:07:54,800 --> 00:07:57,170 é que ela exiba a mesma coisa que nós 145 00:07:57,170 --> 00:08:03,000 obteria se tentamos executar o make em o programa C na janela do terminal. 146 00:08:03,000 --> 00:08:06,230 >> Aqui, podemos ver que está funcionando clang, e que tem uma variedade de bandeiras, 147 00:08:06,230 --> 00:08:12,660 e ele está compilando nosso arquivo count.c, que foi o guia selecionada no momento 148 00:08:12,660 --> 00:08:15,100 que eu bati de depuração. 149 00:08:15,100 --> 00:08:18,010 Então isso é muito útil porque agora usando este botão de depuração, 150 00:08:18,010 --> 00:08:23,280 podemos simultaneamente compilar e, em seguida, executar o programa que nós realmente 151 00:08:23,280 --> 00:08:24,460 deseja executar. 152 00:08:24,460 --> 00:08:27,880 >> Uma das bandeiras que é importante, neste caso, 153 00:08:27,880 --> 00:08:30,190 temos sido realmente usando por mais tempo 154 00:08:30,190 --> 00:08:32,450 mas também só fiz alguma mão acenando [inaudível], que 155 00:08:32,450 --> 00:08:33,820 é este aqui. 156 00:08:33,820 --> 00:08:35,790 Em clang, diz -ggdb3. 157 00:08:35,790 --> 00:08:38,570 158 00:08:38,570 --> 00:08:41,250 Neste caso, o que somos dizendo clang, nosso compilador, 159 00:08:41,250 --> 00:08:43,820 é que nós queremos para compilar nosso programa. 160 00:08:43,820 --> 00:08:46,810 Mas também fornecer o que são chamado de informação símbolo 161 00:08:46,810 --> 00:08:50,940 para que o compilador realmente tem acesso para uma grande parte da informação subjacente 162 00:08:50,940 --> 00:08:52,610 contido dentro do programa. 163 00:08:52,610 --> 00:08:55,260 >> Mais especificamente, o número das funções que eu tenho, 164 00:08:55,260 --> 00:08:58,000 os nomes dessas funções, as variáveis, os tipos 165 00:08:58,000 --> 00:09:01,730 que as variáveis ​​são, e uma variedade de outras coisas que ajudam o depurador 166 00:09:01,730 --> 00:09:04,350 realizar o seu funcionamento. 167 00:09:04,350 --> 00:09:06,600 Agora há mais uma coisa isso é importante mencionar 168 00:09:06,600 --> 00:09:10,280 quando estamos discutindo running um programa deste modo. 169 00:09:10,280 --> 00:09:13,660 >> Observe que ele tem, na verdade, trouxe à tona uma nova guia no nosso console 170 00:09:13,660 --> 00:09:14,780 ao longo do fundo. 171 00:09:14,780 --> 00:09:18,600 Nós já não têm de interagir diretamente com a janela do terminal. 172 00:09:18,600 --> 00:09:21,420 Mas este novo guia é na verdade, uma janela de terminal. 173 00:09:21,420 --> 00:09:26,710 Ela só é específico para o funcionamento programa que criamos. 174 00:09:26,710 --> 00:09:29,270 >> Note-se que na parte inferior, em combinação com alguma saída 175 00:09:29,270 --> 00:09:33,500 por clang o compilador e GDB, qual podemos ignorar em grande parte, 176 00:09:33,500 --> 00:09:37,570 que realmente mostra a saída de nosso programa na parte inferior. 177 00:09:37,570 --> 00:09:41,240 Agora é importante perceber que esta janela realmente 178 00:09:41,240 --> 00:09:43,360 irá mostrar-lhe o saída de seu programa 179 00:09:43,360 --> 00:09:47,190 mas também pode aceitar a entrada para esse programa, bem. 180 00:09:47,190 --> 00:09:49,260 >> Então nota que diz Por favor insira um número, 181 00:09:49,260 --> 00:09:53,050 que é a mesma saída que tinha tinha na janela do terminal antes. 182 00:09:53,050 --> 00:09:55,510 Mas agora é mostrado nesta nova guia. 183 00:09:55,510 --> 00:09:56,550 I pode introduzir um número. 184 00:09:56,550 --> 00:10:00,900 E ele vai realmente função como esperamos 185 00:10:00,900 --> 00:10:05,890 mostrando nosso debug, de saída, a saída que pode ser buggy, 186 00:10:05,890 --> 00:10:07,010 como vimos antes. 187 00:10:07,010 --> 00:10:10,460 E bem no fundo, ele realmente tem alguma saída adicional 188 00:10:10,460 --> 00:10:14,550 do PIB apenas dizendo que este programa foi concluída. 189 00:10:14,550 --> 00:10:16,655 >> Agora, como você viu neste especial de execução por meio, 190 00:10:16,655 --> 00:10:19,370 não foi particularmente útil porque mesmo 191 00:10:19,370 --> 00:10:23,740 embora tivemos o menu depurador vir se, este ainda era um programa em execução. 192 00:10:23,740 --> 00:10:26,790 Em nenhum momento ele realmente pausar a execução para nós 193 00:10:26,790 --> 00:10:30,767 para ser capaz de inspecionar todos as variáveis ​​contidos. 194 00:10:30,767 --> 00:10:32,850 Há algo mais que temos que fazer, a fim 195 00:10:32,850 --> 00:10:36,910 para obter GDB reconhecer que nós queremos para pausar a execução do programa 196 00:10:36,910 --> 00:10:42,820 e não apenas permitir que ele continue normalmente como seria em qualquer outro caso. 197 00:10:42,820 --> 00:10:45,530 >> A fim de parar a execução, em alguma linha específica, 198 00:10:45,530 --> 00:10:47,830 precisamos criar o que é chamado um ponto de ruptura. 199 00:10:47,830 --> 00:10:52,670 E um ponto de quebra é muito facilmente criado neste CS50 IDE, tendo o seu rato 200 00:10:52,670 --> 00:10:57,090 e clicando directamente à esquerda de um número de linha específico. 201 00:10:57,090 --> 00:10:59,920 Uma vez que eu faço isso, um ponto vermelho aparece, o que indica 202 00:10:59,920 --> 00:11:02,300 que essa linha é agora um ponto de ruptura. 203 00:11:02,300 --> 00:11:07,540 >> E da próxima vez que eu corro GDB, esta irá parar a execução nesse ponto de quebra 204 00:11:07,540 --> 00:11:10,280 quando atinge essa linha de código. 205 00:11:10,280 --> 00:11:12,230 Agora, este é um importante coisa a perceber 206 00:11:12,230 --> 00:11:16,140 que não é necessariamente o caso em que cada linha de código 207 00:11:16,140 --> 00:11:17,880 na verdade, é acessível. 208 00:11:17,880 --> 00:11:23,780 Se eu fosse para criar uma função até aqui, para F-- vazio example-- 209 00:11:23,780 --> 00:11:31,230 e apenas fazer uma linha de impressão aqui-- Olá mundo-- se eu nunca chamar esta função, 210 00:11:31,230 --> 00:11:34,770 que será o caso de que, se eu definir um break point aqui, 211 00:11:34,770 --> 00:11:36,220 a função nunca será chamado. 212 00:11:36,220 --> 00:11:38,310 E, por conseguinte, este especial break point 213 00:11:38,310 --> 00:11:43,040 nunca realmente pausa a execução do programa. 214 00:11:43,040 --> 00:11:48,020 >> Então, digamos que eu criar corretamente um ponto de ruptura em algum linha de código 215 00:11:48,020 --> 00:11:50,340 que vai realmente ser executado. 216 00:11:50,340 --> 00:11:53,470 Agora, neste caso, esta é a primeira linha na função principal. 217 00:11:53,470 --> 00:11:56,630 Por isso, será certamente o caso que, assim que eu começar a execução, 218 00:11:56,630 --> 00:11:58,580 a primeira linha será alcançado. 219 00:11:58,580 --> 00:12:00,230 GDB vai parar a execução. 220 00:12:00,230 --> 00:12:04,100 E então, eu serei capaz de interagir com o depurador. 221 00:12:04,100 --> 00:12:08,480 >> Você pode definir várias linhas como pontos de interrupção, se você gostaria. 222 00:12:08,480 --> 00:12:11,365 Nós também podemos criar uma linha para cima aqui neste segmento de código 223 00:12:11,365 --> 00:12:12,490 que nunca será alcançado. 224 00:12:12,490 --> 00:12:14,744 E nós também pode definir uma mais abaixo. 225 00:12:14,744 --> 00:12:16,660 A razão que nós quero fazer isso nós vamos 226 00:12:16,660 --> 00:12:19,119 entrar em um pouco mais detalhes em apenas um momento. 227 00:12:19,119 --> 00:12:21,660 Então, por agora, deixe-me apenas desativar estes pontos de quebra adicionais 228 00:12:21,660 --> 00:12:24,940 para que possamos ver o que acontece quando eu tenho uma única pausa 229 00:12:24,940 --> 00:12:27,650 ponto no meu programa. 230 00:12:27,650 --> 00:12:29,410 Eu fiz alguns alterações a este programa. 231 00:12:29,410 --> 00:12:30,750 Então, eu preciso salvá-lo. 232 00:12:30,750 --> 00:12:34,490 Vou clique debug para que eu possa começar a compilação e, em seguida, 233 00:12:34,490 --> 00:12:36,880 execução do depurador. 234 00:12:36,880 --> 00:12:40,632 >> Veremos que, depois de momentos, os linha que foi selecionada como a quebra 235 00:12:40,632 --> 00:12:43,360 ponto é destacado em amarelo. 236 00:12:43,360 --> 00:12:47,440 Nós também podemos notar que no canto superior direito no painel de debug 237 00:12:47,440 --> 00:12:50,940 que o ícone de pausa se transformou em um pequeno ícone de jogo. 238 00:12:50,940 --> 00:12:54,710 Isto significa que temos de pausa execução, neste caso em particular. 239 00:12:54,710 --> 00:12:57,840 E apertar o botão Reproduzir se permitir-nos continuar a execução 240 00:12:57,840 --> 00:13:00,000 nesse ponto específico. 241 00:13:00,000 --> 00:13:03,240 >> Observe que há um par de outro botões disponíveis neste painel de depuração, 242 00:13:03,240 --> 00:13:04,220 também. 243 00:13:04,220 --> 00:13:09,470 Passar por cima, o que me permite executar que uma linha de código 244 00:13:09,470 --> 00:13:14,030 e passar por cima dessa linha para o seguinte, o que, neste caso, 245 00:13:14,030 --> 00:13:17,060 significaria que o printf instrução é executada. 246 00:13:17,060 --> 00:13:22,310 E, em seguida, fazer uma pausa execução na linha 13, assim. 247 00:13:22,310 --> 00:13:25,090 >> E há também um passo em função, que 248 00:13:25,090 --> 00:13:28,950 é útil se eu criei outro funções em outras partes do código-fonte. 249 00:13:28,950 --> 00:13:31,420 E eu quero entrar essas funções, em vez de 250 00:13:31,420 --> 00:13:33,050 executar essa função como um todo. 251 00:13:33,050 --> 00:13:37,279 Mas vamos olhar mais para o passo em função apenas em um momento. 252 00:13:37,279 --> 00:13:40,320 Agora notar algumas outras coisas que realmente existem dentro deste painel de depuração. 253 00:13:40,320 --> 00:13:44,110 >> Temos este painel de chamada chamar pilha, que nos mostra 254 00:13:44,110 --> 00:13:45,300 exatamente onde estamos. 255 00:13:45,300 --> 00:13:48,550 Neste caso, estamos dentro da função principal. 256 00:13:48,550 --> 00:13:50,880 Nosso script é chamado count.c. 257 00:13:50,880 --> 00:13:53,820 E nós acontecer de ser em linha 13, coluna um, que 258 00:13:53,820 --> 00:13:58,950 é precisamente o que a região em destaque do código fonte indica, como bem. 259 00:13:58,950 --> 00:14:02,435 >> Agora note que isso também mostra sob a seção variável local 260 00:14:02,435 --> 00:14:06,710 todas as variáveis ​​que existem dentro esta função. 261 00:14:06,710 --> 00:14:08,930 É importante notar que todas as variáveis 262 00:14:08,930 --> 00:14:12,580 vai aparecer nesta variável local seção dentro de uma função, 263 00:14:12,580 --> 00:14:14,380 mesmo antes de serem definidas. 264 00:14:14,380 --> 00:14:19,160 Podemos ver aqui que temos uma variável chamado num, tem um valor padrão de 0, 265 00:14:19,160 --> 00:14:21,280 e é do tipo int. 266 00:14:21,280 --> 00:14:24,110 >> Agora, antes de realmente inicializar todas estas variáveis, 267 00:14:24,110 --> 00:14:26,685 nós não somos necessariamente garantido para ver um valor de 0. 268 00:14:26,685 --> 00:14:29,200 E dependendo de outras execuções que você executou 269 00:14:29,200 --> 00:14:32,020 eo estado da sua memória quando você realmente executar este programa, 270 00:14:32,020 --> 00:14:34,605 você pode achar que você Não vejo valores de 0 271 00:14:34,605 --> 00:14:36,550 e, em vez disso, alguns outros números loucos. 272 00:14:36,550 --> 00:14:38,390 >> Mas não se preocupe com isso. 273 00:14:38,390 --> 00:14:44,610 Não vai ser relevante até você realmente inicializar o valor. 274 00:14:44,610 --> 00:14:49,630 Agora, neste caso, podemos ver que Tenho realizado alguns saídas. 275 00:14:49,630 --> 00:14:52,131 E eu estou, agora, parou a execução. 276 00:14:52,131 --> 00:14:53,880 Mas neste caso, o que Eu realmente quero fazer 277 00:14:53,880 --> 00:14:58,060 é para o passo agora sobre esta linha de código para que eu possa realmente 278 00:14:58,060 --> 00:15:04,390 consultar o usuário para que int que nós queremos usar em nosso programa. 279 00:15:04,390 --> 00:15:07,060 >> Agora, neste caso, quando Eu bati passar por cima, aviso 280 00:15:07,060 --> 00:15:11,940 que a pausa ou melhor, o Resume botão mudou a este botão de pausa 281 00:15:11,940 --> 00:15:14,022 porque este código é realmente execução. 282 00:15:14,022 --> 00:15:15,730 O que está acontecendo neste momento é que é 283 00:15:15,730 --> 00:15:21,630 esperando por nós para entrada de algumas informações como podemos ver pelo nosso texto de saída 284 00:15:21,630 --> 00:15:23,600 na parte inferior. 285 00:15:23,600 --> 00:15:25,787 >> Então, agora, este é Não, na verdade, fez uma pausa, 286 00:15:25,787 --> 00:15:28,620 mesmo que, de certa forma, parece ser, porque nada está acontecendo. 287 00:15:28,620 --> 00:15:32,360 Mas isso só acontece que, meu caso específico na linha 13, 288 00:15:32,360 --> 00:15:34,210 Estou aguardando entrada do usuário. 289 00:15:34,210 --> 00:15:39,130 E assim GDB não é capaz de inspecionar um programa como ele está sendo executado. 290 00:15:39,130 --> 00:15:43,370 >> Agora, a próxima vez que eu entrar em alguns input-- então eu vou entrar nesse número 5, 291 00:15:43,370 --> 00:15:46,140 como vimos no past-- bater Return, e nós 292 00:15:46,140 --> 00:15:51,430 notar que, de imediato, pausas GDB e, novamente, destaca a linha seguinte. 293 00:15:51,430 --> 00:15:55,320 Mas note que agora, como um resultado da nossa introduzir um valor, 294 00:15:55,320 --> 00:15:58,930 nós atualizamos esse valor dentro de nossas variáveis ​​locais, que 295 00:15:58,930 --> 00:16:05,560 É muito útil saber com precisão o que esse número estava na memória. 296 00:16:05,560 --> 00:16:10,650 >> Agora posso permitir que este programa continue jogar até ao fim da sua execução 297 00:16:10,650 --> 00:16:12,570 por bater Resume. 298 00:16:12,570 --> 00:16:16,410 Podemos ver que muito rapidamente faz o acabamento programa de execução 299 00:16:16,410 --> 00:16:19,790 com a mesma saída que nós tinha antes, o depurador fecha, 300 00:16:19,790 --> 00:16:23,170 e agora este programa parou completamente. 301 00:16:23,170 --> 00:16:25,320 >> I mostram que apenas pela efeitos de ver o que 302 00:16:25,320 --> 00:16:27,280 acontece quando nós realmente bater Resume. 303 00:16:27,280 --> 00:16:30,640 Mas nós realmente estão indo para quero voltar para este programa 304 00:16:30,640 --> 00:16:33,820 para que possamos tentar depurar precisamente o que está acontecendo. 305 00:16:33,820 --> 00:16:37,980 Agora que eu estou usando o depurador, posso não precisa destas declarações de depuração printf. 306 00:16:37,980 --> 00:16:43,860 >> Assim eu poderia removê-los como eu vou fazer Agora, apenas para voltar para o nosso código mais simples 307 00:16:43,860 --> 00:16:45,950 que tivemos um momento atrás. 308 00:16:45,950 --> 00:16:48,790 Agora, quando eu salvar o programar e executá-lo, 309 00:16:48,790 --> 00:16:53,700 ele irá, mais uma vez, ir para aquele inicial ponto que eu tinha na linha 11 quebrar. 310 00:16:53,700 --> 00:16:57,700 E eu vou ser capaz de inspecionar meus variáveis ​​como eu quero fazer. 311 00:16:57,700 --> 00:17:00,695 >> Acontece que este parte não é muito interessante, 312 00:17:00,695 --> 00:17:04,364 E eu sei que eu vou imprimir esta declaração. 313 00:17:04,364 --> 00:17:05,280 Por favor insira um número. 314 00:17:05,280 --> 00:17:08,099 E então, eu sei que eu vou pedir ao usuário para esse inteiro. 315 00:17:08,099 --> 00:17:13,329 Então, talvez, eu realmente quero mudar a minha ponto de quebrar um pouco mais abaixo. 316 00:17:13,329 --> 00:17:16,710 >> Você pode remover pontos de interrupção clicando, novamente, diretamente 317 00:17:16,710 --> 00:17:18,460 para a esquerda de que o número da linha. 318 00:17:18,460 --> 00:17:22,200 Esse ponto vermelho desaparecerá, indicando que esse ponto de quebra é ido agora. 319 00:17:22,200 --> 00:17:24,780 Agora, no presente caso, execução foi pausada. 320 00:17:24,780 --> 00:17:27,770 E por isso não é realmente indo para retomar nesse caso particular. 321 00:17:27,770 --> 00:17:30,210 Mas eu posso definir uma pausa apontar um pouco mais tarde. 322 00:17:30,210 --> 00:17:33,880 >> E quando eu agora retomar a minha código, ele será retomada e dizer- 323 00:17:33,880 --> 00:17:36,190 a ponto de que ponto de quebra. 324 00:17:36,190 --> 00:17:37,374 Mais uma vez, eu bati Resume. 325 00:17:37,374 --> 00:17:39,040 Não parece que nada está acontecendo. 326 00:17:39,040 --> 00:17:41,450 Mas isso é porque minha código está aguardando entrada. 327 00:17:41,450 --> 00:17:47,900 Vou introduzir um número 5, pressione Enter, e Agora, o próximo ponto de interrupção será atingido. 328 00:17:47,900 --> 00:17:50,570 >> Agora, no presente caso, este é a linha de código 329 00:17:50,570 --> 00:17:53,820 que, antes, sabíamos passou a ser buggy. 330 00:17:53,820 --> 00:17:57,590 Então, vamos avaliar o que acontece neste momento particular no tempo. 331 00:17:57,590 --> 00:18:02,620 Quando uma linha é realçada, este A linha ainda não foi executado. 332 00:18:02,620 --> 00:18:06,490 Portanto, neste caso, podemos ver que eu tenho um número, que 333 00:18:06,490 --> 00:18:11,610 Eu tenho um número inteiro chamado Num que tem um valor 5. 334 00:18:11,610 --> 00:18:15,090 E eu vou estar realizando um pouco de matemática em que número. 335 00:18:15,090 --> 00:18:20,130 >> Se eu passar por cima disso, nós podemos perceber que o valor para o núm 336 00:18:20,130 --> 00:18:23,780 foi alterado de acordo com o aritmética que temos realmente feito. 337 00:18:23,780 --> 00:18:26,810 E agora que estamos dentro deste loop 338 00:18:26,810 --> 00:18:29,090 ou agora que o loop for em si está em destaque, 339 00:18:29,090 --> 00:18:32,450 vemos que temos um novo variável chamada i que 340 00:18:32,450 --> 00:18:35,370 vai ser utilizado na medida em que para o laço. 341 00:18:35,370 --> 00:18:38,230 >> Agora lembre-se antes que eu mencionou que às vezes você está 342 00:18:38,230 --> 00:18:43,470 vai ver algum tipo de louco números como padrão antes de esse número 343 00:18:43,470 --> 00:18:45,530 ou que é variável na verdade inicializado. 344 00:18:45,530 --> 00:18:49,040 Podemos ver que precisamente aqui na presente variável 345 00:18:49,040 --> 00:18:51,345 chamado I, que não possui Ainda não foi inicializado 346 00:18:51,345 --> 00:18:53,560 no momento de destacar. 347 00:18:53,560 --> 00:18:57,070 Mas podemos ver que ele tem algum número que não seria realmente esperar. 348 00:18:57,070 --> 00:18:57,620 >> Isso está ok. 349 00:18:57,620 --> 00:18:59,661 Não se preocupe com isso porque não temos, na verdade, 350 00:18:59,661 --> 00:19:04,970 inicializado esse número até que eu passar por cima desta linha eo valor 351 00:19:04,970 --> 00:19:08,560 i foi inicializado com o valor 1. 352 00:19:08,560 --> 00:19:11,400 Então, para ver que isso é, na verdade, o caso, vamos passar por cima. 353 00:19:11,400 --> 00:19:14,420 Podemos ver agora que esse A linha foi executada. 354 00:19:14,420 --> 00:19:17,000 E agora estamos destacando esta linha printf. 355 00:19:17,000 --> 00:19:22,230 >> E agora podemos ver como os nossos valores de i 3 e mudaram ao longo do tempo. 356 00:19:22,230 --> 00:19:26,450 Isto é muito útil para fazer, na verdade, é para passar por cima de linhas repetidamente. 357 00:19:26,450 --> 00:19:30,480 E você pode encontrar o que realmente acontece dentro de seu loop for 358 00:19:30,480 --> 00:19:33,660 eo que acontece com a variáveis ​​dentro desse loop 359 00:19:33,660 --> 00:19:39,200 como que a execução do programa ocorre um passo de cada vez. 360 00:19:39,200 --> 00:19:41,110 >> Agora, neste momento, eu passou por cima apenas o suficiente 361 00:19:41,110 --> 00:19:44,210 que agora eu estou no final do meu programa. 362 00:19:44,210 --> 00:19:46,980 Se eu passar por cima disso, ele vai realmente cessar execução 363 00:19:46,980 --> 00:19:48,860 como vimos no passado. 364 00:19:48,860 --> 00:19:52,110 Deixe-me reiniciar este, mais uma vez, de modo que eu possa apontar algo mais para fora, 365 00:19:52,110 --> 00:19:53,320 também. 366 00:19:53,320 --> 00:19:55,350 >> Neste caso, é agora me perguntar, de novo, 367 00:19:55,350 --> 00:19:57,100 para um número, o qual Eu vou, mais uma vez, entrar. 368 00:19:57,100 --> 00:20:00,300 Mas desta vez, eu vou entrar em um número maior para que o loop for 369 00:20:00,300 --> 00:20:02,540 irá interagir mais vezes. 370 00:20:02,540 --> 00:20:06,090 Neste caso, eu vou para introduzir um valor de 11. 371 00:20:06,090 --> 00:20:08,390 >> Agora, novamente, porque eu tinha definido um ponto de interrupção na linha 15, 372 00:20:08,390 --> 00:20:10,490 vai destacar essa linha. 373 00:20:10,490 --> 00:20:12,980 Podemos ver que o nosso número 11 é corretamente 374 00:20:12,980 --> 00:20:15,560 representados nos locais variáveis. 375 00:20:15,560 --> 00:20:22,460 Passando por cima disso, podemos agora veja o que acontece ao nosso valor de i 376 00:20:22,460 --> 00:20:25,680 à medida que prosseguimos dentro deste loop. 377 00:20:25,680 --> 00:20:31,960 Ele é incrementado cada vez que chegar ao topo do que para loop. 378 00:20:31,960 --> 00:20:35,110 >> Agora, uma das coisas que podem ser útil para fazer durante a execução 379 00:20:35,110 --> 00:20:40,490 deste programa é para mim, na verdade, mudar o variáveis ​​midstream para ver 380 00:20:40,490 --> 00:20:42,450 o que acontece com o meu programa. 381 00:20:42,450 --> 00:20:46,540 Neste caso, eu posso realmente clique duas vezes o valor. 382 00:20:46,540 --> 00:20:48,040 Observe que torna-se um campo de texto. 383 00:20:48,040 --> 00:20:50,280 >> Agora eu posso entrar diferente Valorizamos completamente 384 00:20:50,280 --> 00:20:55,700 para ver como o meu programa se comporta quando eu mudei essa variável. 385 00:20:55,700 --> 00:20:59,560 Agora, no presente caso, a variável i agora contém o valor 10. 386 00:20:59,560 --> 00:21:02,810 Mas o programa ainda é fez uma pausa na execução. 387 00:21:02,810 --> 00:21:07,610 Quando eu passar por cima, vejo que a valor i, onde entrei como 10, 388 00:21:07,610 --> 00:21:12,170 não é maior do que o valor de num, o que imediatamente faz com que o loop for 389 00:21:12,170 --> 00:21:14,240 para parar a execução. 390 00:21:14,240 --> 00:21:16,210 >> Agora que não é o único razão pela qual você faria 391 00:21:16,210 --> 00:21:19,450 quer modificar a variável no lugar. 392 00:21:19,450 --> 00:21:22,210 Você pode realmente querem para tentar modificá-lo para 393 00:21:22,210 --> 00:21:24,590 que possa continuar execução de um ciclo 394 00:21:24,590 --> 00:21:27,370 ou para que você possa modificar algum valor antes 395 00:21:27,370 --> 00:21:32,630 atinge algum conjunto específico de aritmética que você está prestes a realizar. 396 00:21:32,630 --> 00:21:36,210 >> Portanto, agora que nós realmente mudar a valor de i que o programa estava sendo executado, 397 00:21:36,210 --> 00:21:39,540 que causou o loop for para sair prematuramente, porque, de repente, eu 398 00:21:39,540 --> 00:21:42,770 Aconteceu a ser maior do que o valor de num, o que significa que esse loop 399 00:21:42,770 --> 00:21:45,410 não é mais necessário para ser executado. 400 00:21:45,410 --> 00:21:48,780 Além disso, ele passou a ser o caso que nós mudamos o valor de i 401 00:21:48,780 --> 00:21:53,270 quando a linha 17 foi destaque, que foi o ponto no tempo 402 00:21:53,270 --> 00:21:56,280 para que a execução do loop foi, na verdade, está sendo avaliado. 403 00:21:56,280 --> 00:22:00,210 >> Se eu tivesse alterado o valor da i em uma linha diferente, digamos 19, 404 00:22:00,210 --> 00:22:03,360 teríamos visto diferente comportamento porque linha 19 seria 405 00:22:03,360 --> 00:22:08,310 ter executado antes do loop condição foi reavaliada. 406 00:22:08,310 --> 00:22:11,900 Agora, neste momento, eu estou, novamente, no final deste programa. 407 00:22:11,900 --> 00:22:15,707 E posso permitir que isso continue a permitir que o meu programa para sair naturalmente. 408 00:22:15,707 --> 00:22:18,290 Mas há um par de coisas que são importantes para tirar 409 00:22:18,290 --> 00:22:19,960 a partir desta discussão especial. 410 00:22:19,960 --> 00:22:22,490 Você precisa avaliar suas próprias suposições 411 00:22:22,490 --> 00:22:24,710 sobre como o código deve estar se comportando. 412 00:22:24,710 --> 00:22:28,220 Toda vez que você pensar que alguma peça de código que você sabe acontece para trabalhar, 413 00:22:28,220 --> 00:22:30,940 que pode ser uma bandeira vermelha para ir para trás e avaliar, e ter a certeza 414 00:22:30,940 --> 00:22:33,470 que a sua assunção de como que o código está a funcionar 415 00:22:33,470 --> 00:22:38,290 é realmente verdade de como ele é expressa em seu código fonte. 416 00:22:38,290 --> 00:22:41,300 >> Mas ainda mais a questão era, quando estamos usando o depurador, 417 00:22:41,300 --> 00:22:43,920 você pode colocar pontos de interrupção em diferentes linhas de código, 418 00:22:43,920 --> 00:22:48,110 o que fará com que o depurador pausar a execução em cada uma dessas linhas 419 00:22:48,110 --> 00:22:52,210 para que você possa avaliar a memória ou até mesmo alterá-lo no lugar. 420 00:22:52,210 --> 00:22:55,630 E, novamente, lembre-se que você pode criar vários pontos de interrupção para que você 421 00:22:55,630 --> 00:23:00,390 Também pode retomar a execução, pule ao longo de grandes porções de código, 422 00:23:00,390 --> 00:23:04,790 e ele vai parar automaticamente no próximo ponto de quebra. 423 00:23:04,790 --> 00:23:07,760 >> Há realmente mais avançado recursos do depurador, bem. 424 00:23:07,760 --> 00:23:10,170 Mas nós vamos ter que encaminhá-lo para alguns vídeos subsequentes 425 00:23:10,170 --> 00:23:14,090 a fim de realmente provocar uma separação como para usar essas funções específicas. 426 00:23:14,090 --> 00:23:15,990 Por agora, obrigado muito para ver. 427 00:23:15,990 --> 00:23:18,080 E boa sorte depuração.