1 00:00:07,170 --> 00:00:12,630 [Powered by Google Translate] GDB, o GNU Project Debugger, é uma poderosa ferramenta de depuração para C, 2 00:00:12,630 --> 00:00:14,300 juntamente com muitas outras línguas. 3 00:00:14,300 --> 00:00:17,440 Ele permite que você bisbilhotar dentro seus programas de C, enquanto eles estão em execução, 4 00:00:17,440 --> 00:00:20,880 e dá-lhe também a oportunidade de ver exatamente o que acontece 5 00:00:20,880 --> 00:00:22,490 quando falha de seu programa. 6 00:00:22,490 --> 00:00:24,690 É muito bacana, certo? 7 00:00:24,690 --> 00:00:27,980 GDB é um software livre, e funciona em muitos UNIX popular e 8 00:00:27,980 --> 00:00:31,840 Sistemas operacionais baseados no Windows, por isso é uma ferramenta muito difundida. 9 00:00:31,840 --> 00:00:33,560 >> Você deve aprender a amá-lo. 10 00:00:33,560 --> 00:00:36,800 Prós GDB ter um tempo muito mais fácil rastrear erros 11 00:00:36,800 --> 00:00:39,150 do que aqueles que inverter a ordem e usando suposições 12 00:00:39,150 --> 00:00:41,420 e quantidades infinitas de declarações da impressão. 13 00:00:41,420 --> 00:00:45,810 GDB é uma ferramenta de linha de comando, o que significa que você pode interagir com ela em um terminal 14 00:00:45,810 --> 00:00:49,720 emitir comandos através do teclado em vez de botões clicando com o mouse. 15 00:00:49,720 --> 00:00:54,960 >> Para iniciar o GDB, você literalmente apenas gdb no prompt e tecle enter. 16 00:00:54,960 --> 00:00:58,230 Você verá algumas linhas impressas para a tela 17 00:00:58,230 --> 00:01:00,810 mostrando a versão do GDB que você está executando, 18 00:01:00,810 --> 00:01:07,890 sua informação de copyright, e no final você vai ver o prompt GDB: (gdb). 19 00:01:07,890 --> 00:01:10,770 Isso permite que você saiba que o GDB está pronto para comandos. 20 00:01:10,770 --> 00:01:15,400 Neste ponto, a coisa mais importante que saber fazer é parar de fumar. 21 00:01:15,400 --> 00:01:17,790 Felizmente, isso é muito simples. 22 00:01:17,790 --> 00:01:19,840 O comando quit faz exatamente isso. 23 00:01:19,840 --> 00:01:23,090 Como um atalho, você pode apenas usar q também. 24 00:01:23,090 --> 00:01:27,410 Tão divertido quanto arrancar GDB e prontamente parar de fumar é, 25 00:01:27,410 --> 00:01:30,800 Vamos agora falar sobre o uso de GDB para ajudar a depurar um programa. 26 00:01:30,800 --> 00:01:34,630 >> Para começar, eu tenho um programa aqui em factorial.c 27 00:01:34,630 --> 00:01:37,380 que recebe um int e tenta calcular o seu fatorial. 28 00:01:37,380 --> 00:01:41,270 No caso você não tenha visto antes fatoriais ou não se lembra deles, 29 00:01:41,270 --> 00:01:47,840 O fatorial do número n é igual ao produto de n - (n - 1), (n - 2), e assim por diante - 30 00:01:47,840 --> 00:01:49,230 até que você bata um. 31 00:01:49,230 --> 00:01:54,550 Portanto, o factorial de 3 é 3 * 2 * 1, ou 6, 32 00:01:54,550 --> 00:02:00,180 e que o fatorial de 4 é 4 * 3 * 2 * 1, ou 24. 33 00:02:00,180 --> 00:02:03,970 O fatorial de zero é um caso estranho, é um, 34 00:02:03,970 --> 00:02:06,970 e os fatoriais de inteiros negativos não estão definidas. 35 00:02:06,970 --> 00:02:10,280 De qualquer forma, algo sobre o meu programa fatorial é funky. 36 00:02:10,280 --> 00:02:15,410 Quando eu executá-lo, ele imprime os números estranhos que nada têm a ver com fatoriais. 37 00:02:15,410 --> 00:02:19,030 >> Assim, podemos usar o GDB para ajudar a descobrir o que está acontecendo. 38 00:02:19,030 --> 00:02:21,720 GDB opera em arquivos executáveis, 39 00:02:21,720 --> 00:02:24,910 que são os ficheiros binários produzidos pelo processo de compilação. 40 00:02:24,910 --> 00:02:30,940 Isto é, não podemos correr o GDB em nosso c. Ou. Arquivos de origem h código como factorial.c. 41 00:02:30,940 --> 00:02:34,650 Nós queremos executá-lo em apenas fatorial vez. 42 00:02:34,650 --> 00:02:38,340 Se o programa necessário quaisquer argumentos de linha de comando, 43 00:02:38,340 --> 00:02:40,230 este é o lugar onde nós especificá-los. 44 00:02:40,230 --> 00:02:44,050 Neste caso, fatorial não necessita de quaisquer argumentos de linha de comando, 45 00:02:44,050 --> 00:02:46,410 então apenas digitar corrida ou r para breve. 46 00:02:46,410 --> 00:02:50,440 >> Isto irá iniciar a execução do programa fatorial. 47 00:02:50,440 --> 00:02:53,940 Quando o programa pára de correr, eu vou buscar o meu GDB pedir de volta. 48 00:02:53,940 --> 00:02:58,130 Ok, vamos tentar a mesma coisa de novo, fatorial 4. 49 00:02:58,130 --> 00:03:02,910 Tudo bem, vemos que estamos recebendo o mesmo tipo de lixo aqui no GDB. 50 00:03:02,910 --> 00:03:04,850 Agora que o programa terminou, 51 00:03:04,850 --> 00:03:06,870 não podemos entrar e acessar qualquer de seu estado, 52 00:03:06,870 --> 00:03:09,870 por isso precisamos iniciá-lo funcionando novamente antes que possamos ver o que está acontecendo. 53 00:03:09,870 --> 00:03:13,570 No entanto, precisamos de uma maneira de pará-lo enquanto ele está no meio de sua execução. 54 00:03:13,570 --> 00:03:16,970 >> Para isso, usamos o que é chamado um ponto de interrupção. 55 00:03:16,970 --> 00:03:21,880 Breakpoints dizer GDB para pausar o programa em uma determinada função ou linha de código fonte 56 00:03:21,880 --> 00:03:24,070 de modo que podemos verificar o estado do programa, 57 00:03:24,070 --> 00:03:27,380 os valores de variáveis, o estado da memória e como, neste ponto. 58 00:03:27,380 --> 00:03:30,750 Desde que eu realmente não sei onde as coisas estão indo mal, 59 00:03:30,750 --> 00:03:33,510 >> Eu só quero começar a depuração logo no início, 60 00:03:33,510 --> 00:03:36,510 direito ao principal começa. 61 00:03:36,510 --> 00:03:39,260 Vamos definir um ponto de interrupção no início da principal usando o comando break. 62 00:03:39,260 --> 00:03:42,640 Nós também podemos usar b para abreviar pausa. 63 00:03:42,640 --> 00:03:45,000 Agora vamos iniciar o programa funcionando novamente. 64 00:03:45,000 --> 00:03:48,140 Aqui estamos no início do principal, assim como o GDB nos diz. 65 00:03:48,140 --> 00:03:51,970 A linha de código que está prestes a executar, mas ainda não 66 00:03:51,970 --> 00:03:53,480 é a linha printf. 67 00:03:53,480 --> 00:03:57,200 Podemos dizer GDB para executar esta linha de código e ir para a próxima linha 68 00:03:57,200 --> 00:03:59,840 com o próximo comando ou n. 69 00:03:59,840 --> 00:04:04,120 >> Tudo bem, agora GDB diz-nos que estamos na linha de GetInt. 70 00:04:04,120 --> 00:04:06,630 Eu sei que parece que a linha printf não correr 71 00:04:06,630 --> 00:04:10,070 desde que não vemos "Digite um inteiro positivo" impressão na tela, 72 00:04:10,070 --> 00:04:12,040 mas se realmente executado. 73 00:04:12,040 --> 00:04:16,029 O que estamos vendo é o sistema operacional suprimir qualquer coisa escrita para a tela 74 00:04:16,029 --> 00:04:19,649 até que seja absolutamente necessário, que por depuração com impressões 75 00:04:19,649 --> 00:04:21,730 às vezes pode parecer pouco confiáveis. 76 00:04:21,730 --> 00:04:26,240 Enfim, vamos mais uma vez ir para a próxima linha de código e entrar em um int. 77 00:04:26,240 --> 00:04:30,070 Novamente, vamos tipo 4. 78 00:04:30,070 --> 00:04:34,540 Portanto, este parece estranho. Estamos na linha 12 de acordo com o GDB, 79 00:04:34,540 --> 00:04:37,660 mas a próxima linha que está prestes a executar é apenas uma cinta encaracolado. 80 00:04:37,660 --> 00:04:42,110 >> Isso só significa que estamos no final de um ciclo, o nosso fazer enquanto laço de fato, 81 00:04:42,110 --> 00:04:46,710 GDB e está nos dizendo que a condição de término, ou seja, nada menos que zero, 82 00:04:46,710 --> 00:04:48,010 será executado em seguida. 83 00:04:48,010 --> 00:04:50,230 Se isso nunca fica um pouco confuso, 84 00:04:50,230 --> 00:04:54,860 podemos puxar o código fonte em GDB com a lista ou o comando l. 85 00:04:54,860 --> 00:04:56,880 Este imprime o código fonte 86 00:04:56,880 --> 00:04:59,010 que está centrado em torno da linha que estamos no momento. 87 00:04:59,010 --> 00:05:03,590 Se tipo de lista ou l novamente, vamos ver o próximo conjunto de linhas impressas. 88 00:05:03,590 --> 00:05:06,070 Podemos fazer isso até chegarmos ao final do arquivo. 89 00:05:06,070 --> 00:05:11,210 >> Para voltar para onde estávamos, nós podemos fornecer lista com um número de linha, 90 00:05:11,210 --> 00:05:14,120 neste caso, linha 12. 91 00:05:14,120 --> 00:05:16,040 Enfim, vamos seguir em frente. 92 00:05:16,040 --> 00:05:18,240 Agora estamos no loop 4. 93 00:05:18,240 --> 00:05:21,490 Vamos ter certeza de que a nossa variável num contém 4. 94 00:05:21,490 --> 00:05:26,170 Fazemos isso com a impressão, ou p, de comando. 95 00:05:26,170 --> 00:05:31,140 Então, o GDB nos diz que num é de fato armazenar 4, como esperávamos. 96 00:05:31,140 --> 00:05:35,180 Os US $ 1 que imprime GDB é uma variável GDB especial 97 00:05:35,180 --> 00:05:37,720 que já está definido para armazenar o número 4 também. 98 00:05:37,720 --> 00:05:42,240 Você pode ignorar isso por enquanto, mas essas variáveis ​​GDB vêm em super handy 99 00:05:42,240 --> 00:05:46,380 nos casos mais avançados, quando você quer se lembrar do que você fez no passado. 100 00:05:46,380 --> 00:05:50,970 De qualquer forma, se movendo com a seguinte, vemos que começar a se mover através do loop for. 101 00:05:50,970 --> 00:05:54,790 Vamos continuar por aqui com n bits por pouco. 102 00:05:54,790 --> 00:05:58,280 Em vez de digitar n cada vez, você também pode simplesmente pressionar enter. 103 00:05:58,280 --> 00:06:03,710 Quando você bate entrar sem digitar nada, GDB apenas repete o comando anterior. 104 00:06:03,710 --> 00:06:05,910 Então agora nós batemos a chamada printf. 105 00:06:05,910 --> 00:06:09,520 Parece que temos de fato passou por nosso laço for 4 vezes, 106 00:06:09,520 --> 00:06:13,750 que é o que nós queremos fazer, a fim de multiplicar por 1, 2, 3, e 4. 107 00:06:13,750 --> 00:06:15,870 >> Tudo parece que está funcionando, 108 00:06:15,870 --> 00:06:19,680 exceto quando bateu próximo novamente temos essa grande número em vez de 24. 109 00:06:19,680 --> 00:06:23,100 Se imprimir o valor de p usando fatorial, 110 00:06:23,100 --> 00:06:26,120 vemos que fatorial tem esse enorme número nele. 111 00:06:26,120 --> 00:06:28,740 Algo está definitivamente errado. 112 00:06:28,740 --> 00:06:31,960 Neste ponto, no entanto, que são quase no final do programa, 113 00:06:31,960 --> 00:06:34,610 e é tarde demais para corrigir alguma coisa. 114 00:06:34,610 --> 00:06:39,750 >> No entanto, pode reiniciar o programa, digitando r novamente e então y para confirmar. 115 00:06:39,750 --> 00:06:43,460 Agora estamos de volta ao nosso ponto de interrupção no início da principal. 116 00:06:43,460 --> 00:06:46,600 Sabemos que tudo parece estar bem com a leitura no n. 117 00:06:46,600 --> 00:06:48,630 para que possamos ir em frente com n. 118 00:06:48,630 --> 00:06:52,280 Como alternativa, pode-se definir um novo ponto de interrupção após o fazer loop while 119 00:06:52,280 --> 00:06:54,910 e saltar lá. Vamos fazer isso. 120 00:06:54,910 --> 00:06:59,080 Parece que a linha 14 vem logo após o loop. 121 00:06:59,080 --> 00:07:01,070 Vamos definir um ponto lá. 122 00:07:01,070 --> 00:07:05,220 É uma boa prática para especificar o nome do arquivo neste comando breakpoint 123 00:07:05,220 --> 00:07:08,480 desde GDB pode ficar confuso se você está trabalhando com vários arquivos. 124 00:07:08,480 --> 00:07:13,230 Para avançar deste ponto de interrupção, vamos usar o comando continue ou c. 125 00:07:13,230 --> 00:07:16,570 >> Ok, aqui estamos no loop. 126 00:07:16,570 --> 00:07:19,060 Vamos linha 1 mais no loop for, 127 00:07:19,060 --> 00:07:21,630 e depois nós vamos começar variáveis ​​de impressão para ver o que está acontecendo. 128 00:07:21,630 --> 00:07:26,410 Vamos ter certeza de que eu é de fato um, como esperado. 129 00:07:26,410 --> 00:07:28,300 Sim, isso é tudo de bom. 130 00:07:28,300 --> 00:07:30,270 E sobre fatorial embora? 131 00:07:30,270 --> 00:07:33,760 Uau, isso não é bom. 132 00:07:33,760 --> 00:07:35,800 Temos um grande número negativo aqui. 133 00:07:35,800 --> 00:07:38,190 Como isso aconteceu? 134 00:07:38,190 --> 00:07:40,040 Bem, se olharmos para o código, 135 00:07:40,040 --> 00:07:44,800 vemos que nunca inicializado, então nós só tenho lixo lá. 136 00:07:44,800 --> 00:07:46,820 Isso definitivamente vai jogar fora o nosso cálculo. 137 00:07:46,820 --> 00:07:49,930 >> Felizmente, não temos de deixar GDB para corrigir isso. 138 00:07:49,930 --> 00:07:54,590 Podemos inicializá-lo aqui e corrigi-lo no código mais tarde usando o comando de impressão. 139 00:07:54,590 --> 00:07:59,500 Nós vamos inicializá-lo para 1 desde os fatoriais de zero e um são ambos 1, 140 00:07:59,500 --> 00:08:03,940 e se inicializá-lo para zero, então nós sempre acabam com zero, como o nosso resultado. 141 00:08:03,940 --> 00:08:08,370 Você pode definir qualquer maneira esta variável, que é super acessível. 142 00:08:08,370 --> 00:08:10,920 Agora, vamos continuar o nosso programa. 143 00:08:10,920 --> 00:08:14,040 Vamos ter certeza que tudo está onde deveria estar. 144 00:08:14,040 --> 00:08:19,090 Num deve ser de 4, eu deveria ser 1, e fatorial deve ser um também. 145 00:08:19,090 --> 00:08:23,990 Podemos atalho este processo e imprimir todos os nossos variáveis ​​locais 146 00:08:23,990 --> 00:08:26,440 com os super-úteis locais comando info, 147 00:08:26,440 --> 00:08:29,190 que imprime todos os nossos no escopo de variáveis ​​locais. 148 00:08:29,190 --> 00:08:31,980 De qualquer forma, parece que tudo é bom para ir. 149 00:08:31,980 --> 00:08:34,700 >> Vamos fazer um outro go-around do circuito só para ter certeza. 150 00:08:34,700 --> 00:08:38,789 Ok, tudo parece ótimo. 151 00:08:38,789 --> 00:08:41,659 Agora podemos usar o comando continuam a ir até o fim. 152 00:08:41,659 --> 00:08:46,170 Sweet! Fatorial 4 impressas 24 como esperado. 153 00:08:46,170 --> 00:08:48,690 Agora podemos ir corrigir isso no nosso código. 154 00:08:48,690 --> 00:08:53,710 Em vez de sair fora do GDB, vamos usar outra guia terminal para fazer isso. 155 00:08:53,710 --> 00:08:58,080 Voltando ao nosso guia GDB, agora precisamos recompilar nosso executável. 156 00:08:58,080 --> 00:09:03,180 Uma das melhores coisas sobre o GDB é que você não precisa sair de GDB para executar fazer. 157 00:09:03,180 --> 00:09:06,570 Assim que nós não continuar batendo os pontos de interrupção de idade, 158 00:09:06,570 --> 00:09:10,440 vamos desabilitá-los com o, você adivinhou, desativar comando. 159 00:09:10,440 --> 00:09:13,320 Isto irá desativar todos os nossos pontos de interrupção. 160 00:09:13,320 --> 00:09:18,180 Agora, podemos reiniciar o programa com R e se certificar que tudo está bem. 161 00:09:18,180 --> 00:09:21,300 Parece que tudo o que é bom para ir. 162 00:09:21,300 --> 00:09:24,410 Fatorial de 4 imprime 24, assim como pensávamos. 163 00:09:24,410 --> 00:09:28,830 GDB é uma das ferramentas mais úteis que você tem em sua caixa de ferramentas. 164 00:09:28,830 --> 00:09:31,970 >> Há coisas que uma tonelada mais você pode fazer com o GDB, 165 00:09:31,970 --> 00:09:34,030 muito mais do que você pode fazer com impressões simples. 166 00:09:34,030 --> 00:09:36,730 Da próxima vez que o programa não é fazer o que você quiser, 167 00:09:36,730 --> 00:09:39,740 tente executar GDB para descobrir o que está acontecendo lá dentro. 168 00:09:39,740 --> 00:09:44,380 Com um pouco de prática, você vai ser capaz de pesquisar na sua bug em nenhum momento. 169 00:09:44,380 --> 00:09:48,180 Meu nome é Nate Hardison. Este é CS50.