DOUG LLOYD: Tudo bem GDB. O que é isso exatamente? Então GDB, que significa para o GNU Debugger, é uma ferramenta realmente incrível que podemos usar para nos ajudar a depurar os nossos programas, ou descobrir onde as coisas são acontecendo de errado em nossos programas. GDB é incrivelmente poderoso, mas a saída e interacção com ele pode ser um pouco enigmática. Geralmente é uma ferramenta de linha de comando, e ele pode jogar um monte de mensagens para você. E pode tipo de difícil analisar exatamente o que está acontecendo. Passos Felizmente, temos tido para corrigir esse problema para você como você trabalha através CS50. Se você não estiver usando a gráfica depurador, que o meu colega Dan Armandarse tem falado bastante um pouco sobre em um vídeo que deve ser por aqui agora, você pode precisar para usá-los linha de comando ferramentas para trabalhar com o GDB. Se você estiver trabalhando no CS50 IDE, você não precisa fazer isso. Mas se você não é trabalhando no CS50 IDE, talvez usando uma versão CS50 de Appliance, ou operar outro Linux sistema com GDB instalado nele, você pode precisar usar essas ferramentas de linha de comando. E uma vez que você pode tem que fazer isso, é útil apenas para entender como GDB trabalha na linha de comando. Mas, novamente, se você estiver usando a IDE CS50, você pode usar o depurador gráfico que está incorporado no IDE. Então, para começar as coisas com GDB, para iniciar a depuração processo de um determinado programa, tudo que você precisa fazer é tipo GDB seguido pelo nome do programa. Assim, por exemplo, se o seu programa é Olá, você deverá digitar GDB Olá. Quando você faz isso, você está indo para puxar para cima o ambiente GDB. O prompt vai mudar, e em vez de ser o que é normalmente é quando você digita coisas nas ls linha-- comando, cd-- todo o seu típico Os comandos do Linux, seu prompt mudará para, provavelmente, algo como parênteses GDB parênteses. Esse é o seu novo prompt GDB, porque você está dentro do ambiente GDB. Uma vez dentro desse ambiente, há dois grandes comandos que você provavelmente vai usar na seguinte ordem. O primeiro é b, que é curto para o intervalo. E depois que você digite b, você normalmente digite o nome de uma função, ou se acontecer de você saber em torno do que o número da linha o programa está começando comportar-se um pouco estranho, você pode digitar uma linha Número de lá também. O que b, ou fim, faz é que permite que seu programa para executar até um certo ponto, nomeadamente, o nome da função que você especificar ou a linha número que você especificar. E nesse ponto, vai congelar a execução. Isso é uma coisa muito boa, porque uma vez que a execução tenha sido congelada, você pode começar a muito lentamente passo através de seu programa. Normalmente, se você estive correndo seus programas, eles são muito curta. Normalmente, você digita o que quer barra dot o nome do seu programa, pressione a tecla Enter, e antes que você pode piscar, o seu programa já está terminado. Não é realmente um monte de tempo para tentar e descobrir o que está acontecendo de errado. Por isso, para ser realmente capaz de retardar as coisas para baixo, definindo um ponto de ruptura com b, e, em seguida, pisar em. Então uma vez que você tenha definido a sua pausa ponto, você pode executar o programa. E se você tem qualquer argumentos de linha de comando, você especificá-los aqui, e não quando GDB você digita seu nome do programa. Você especifica toda a linha de comando argumentos, tomando r, ou correr, e, em seguida argumentos de linha de comando que quer você precisa dentro do seu programa. Há um número de outro realmente comandos importantes e úteis no interior do ambiente de PIB. Então deixem-me apenas rapidamente passar por cima de alguns deles. A primeira é a N, que é a abreviação para a próxima, e você pode digitar próximo em vez de n, tanto iria funcionar. E isso é apenas a taquigrafia. E, como você provavelmente já obtido acostumado, ser capaz de escrever coisas mais curto é geralmente melhor. E o que ele vai fazer é que vai avançar um bloco de código. Por isso vai avançar até que uma chamada de função. E, em seguida, em vez de mergulho em que a função e passando por todos que as funções código, ele só vai ter a função. A função será chamado. Ele vai fazer o que seu trabalho é. Ele irá retornar um valor para a função que o chamou. E então você vai passar para a próxima linha de que a função de chamada. Se você quiser passo dentro da função, em vez de ter apenas ele executar, especialmente se você acha que o problema poderia estar dentro dessa função, você poderia, é claro, definir uma pausa ponto no interior dessa função. Ou, se você já está em execução, você pode usar s para avançar uma linha de código. Então, isso vai intervir e mergulhar em funções, em vez de apenas ter a executar e continuando na função que você está em para depuração. Se você sempre quis saber o valor de uma variável, você pode digitar p, ou impressão, e, em seguida, o nome da variável. E que irá imprimir a você, no interior do ambiente de GDB, o nome da variável, que vocę-- com licença mim-- o valor da variável que você tenha nomeado. Se você quiser saber os valores de todas as variável acessível locais de onde você está atualmente em sua programa, você pode digitar informações locais. É muito mais rápido do que digitando p e, em seguida, qualquer que seja, listando todas as variáveis ​​que você sabe que existem. Você pode digitar informações locals, e irá imprimir tudo para você. Em seguida é bt, que é curto para Voltar Trace. Agora, geralmente, particularmente no início do CS50, você realmente não vai ter ocasião usar bt, ou Back Trace, porque você não está tendo funções que chamar outras funções. Você pode ter uma página call função, mas isso é provavelmente isso. Você não tem outra função que chamar outra função, que chama outra função, e assim por diante. Mas, como seus programas obter mais complexo, e particularmente quando você começar a trabalhar com recursividade, traço de volta pode ser uma maneira muito útil para deixá-lo tipo de obter algum contexto para onde Estou no meu programa. Então, digamos que você tenha escrito o seu código, e você sabe que a principal chama uma função f, que chama uma função g, o que chama uma função h. Portanto, temos várias camadas de nidificação acontecendo aqui. Se você estiver dentro de seu ambiente GDB, e você sabe que seu interior de h, mas você esquecer sobre o que você tem para onde você é-- você pode digitar bt, ou traço de volta, e ele vai imprimir h, g, f principal, juntamente com algumas outras informações, que dá-lhe um indício de que, principal OK chamado f, f chamado g, h g de chamada, e é aí que eu Atualmente estou no meu programa. Por isso, pode ser realmente útil, especialmente como o enigmático-ness do GDB torna-se um pouco esmagadora, a descobrir exatamente onde as coisas estão. Por último, quando o programa é feito, ou quando você está feito depurá-lo e você quer se afastar a partir do ambiente de GDB, que ajuda a saber como sair dela. Você pode digitar q, ou Sair, para sair. Agora, antes de vídeo de hoje Preparei um programa de buggy chamado Buggy1, que eu compilei a partir de um arquivo conhecido como buggy1.c. Como você poderia esperar, este programa é, de facto, buggy. Algo vai mal quando eu tentar executá-lo. Agora, infelizmente, eu inadvertidamente apaguei meu arquivo buggy1.c, Então, para mim descobrir o que está acontecendo de errado com este programa, Eu vou ter que usar GDB tipo de cegamente, tentando para navegar através deste programa para descobrir exatamente o que está acontecendo de errado. Mas usando apenas as ferramentas já aprendemos sobre, que pode muito bem figura exatamente o que é. Então vamos cabeça para CS50 IDE e dar uma olhada. OK, por isso estamos aqui na minha CS50 ambiente IDE, e eu vou fazer zoom um pouco assim você pode ver um pouco mais. Na minha janela do terminal, se eu listo o conteúdo da minha atual diretor com ls, vamos ver que eu tenho um par de arquivos de origem aqui, incluindo o anteriormente discutida Buggy1. O que exatamente acontece quando Eu tento e executar Buggy1. Bem, vamos descobrir. Eu digito barra ponto, carrinho, e eu pressione Enter. Falhas de segmentação. Isso não é bom. Se você lembrar, uma falha de segmentação tipicamente ocorre quando acessar a memória que não estamos autorizados a tocar. Temos alguma forma atingido fora dos limites do que o programa, o compilador, nos deu. E assim já que é um pista para manter-se na caixa de ferramentas à medida que começamos o processo de depuração. Algo deu um pouco errado aqui. Tudo bem, então vamos começar o ambiente GDB e ver se podemos descobrir o que exatamente é o problema. Eu estou indo para limpar a tela do computador, e eu estou indo para digitar GDB novamente, para entrar no ambiente GDB, e o nome do programa que eu quero depurar, Buggy1. Recebemos uma pequena mensagem, lendo símbolos de Buggy1, feito. Tudo o que significa é que puxou juntos todo o código, e agora ele foi carregado em GDB, e está pronto para ir. Agora, o que eu quero fazer? Você se lembra o que o primeiro passo é tipicamente depois que eu estou dentro deste ambiente? Com sorte, você referido conjunto um ponto de ruptura, porque na verdade, é isso que eu quero fazer. Agora, eu não tenho o código fonte para este na minha frente, o que é, provavelmente, não é o caso de uso típico, por sinal. Você provavelmente irá ocorrer. Então, isso é bom. Mas supondo que você não fizer isso, o que é a uma função que você sabe existe em cada programa C single? Não importa quão grande ou quão complicado que é, definitivamente, essa função existe. Main, certo? Então, não de tudo, nós podemos definir um ponto de ruptura na principal. E novamente, eu poderia simplesmente digitar quebrar principal, em vez de b. E se você estiver curioso, se você nunca digitar um comando longo e, em seguida, perceber que você digitado a coisa errada, e você quer se livrar de todos, como eu fiz, você pode assumir o controle U, que será apagar tudo e trazer você de volta para o início das linhas do cursor. Um muito mais rápido do que apenas mantenha pressionada a excluir ou batê-lo vezes grupo sobre. Então, vamos definir um break point no principal. E como você pode ver, ele diz que nós temos definir um ponto de interrupção no arquivo buggy1.c, e, aparentemente, a primeira linha de código de linha principal é sete. Novamente, não temos o arquivo de origem aqui, mas eu vou assumir que é me dizendo a verdade. E então, eu só estou tentando e executar o programa, r. A partir do programa. Tudo bem, então esta mensagem é um pouco enigmática. Mas, basicamente, o que é acontecendo aqui é que é apenas me dizendo que eu bati minha pausa ponto, quebra ponto número um. E então, essa linha de código, Não existe tal arquivo ou diretório. A única razão que Eu estou vendo essa mensagem é porque eu inadvertidamente apaguei meu arquivo buggy.c. Se meu arquivo buggy1.c existiu no diretório atual, esse direito linha haveria realmente me diga o que a linha de código literalmente lê. Infelizmente, eu deletei. Nós vamos ter que tipo de navegar através deste um pouco mais cegamente. OK, então vamos ver, o que que eu quero fazer aqui? Bem, eu gostaria de saber o que locais talvez variáveis ​​estão disponíveis para mim. Eu comecei o meu programa. Vamos ver o que pode ser já inicializada para nós. Eu digito moradores Info, não moradores. Tudo bem, de modo que não faz dá-me uma tonelada de informações. Eu poderia tentar e imprimir uma variável, mas eu não sei todos os nomes de variáveis. Eu poderia tentar um traço de volta, mas eu estou dentro de principal, então eu sei que não fizeram outra chamada agora função. Então, parece que minhas únicas opções são usar n ou assim e começar a mergulhar. Eu vou usar n. Então eu digito n. Oh meu Deus, o que está acontecendo aqui. Programa de sinais recebidos, SIGSEGV falha de segmentação, e, em seguida, um monte de coisas. Eu já estou sobrecarregado. Bem, há realmente uma muito a ser aprendido aqui. Então, o que isso nos diz? O que isso nos diz é, este programa é a ponto de, mas não tem ainda, falha seg. E, em particular, eu vou para ampliar ainda mais aqui, é sobre a culpa sobre SEG algo chamado strcmp. Agora, nós não pode ter discutido esta função extensivamente. Mas é-- porque nós não vamos para falar sobre cada função que existe no padrão C library-- mas eles estão todos disponíveis para você, especialmente se você tomar um olhar para reference.cs50.net. E strcmp é um realmente poderoso função que existe dentro do cabeçalho string.h arquivo, o que é um cabeçalho arquivo que é dedicado a funções que o trabalho com e manipular strings. E, em particular, o que faz é strcmp compara os valores de duas cordas. Então, eu estou prestes a falha de segmentação em uma chamada à strcmp parece. Eu bati n, e na verdade eu receber a mensagem, programa terminou com sinal SIGSEGV falha de segmentação. Então agora Na verdade, tenho seg criticado, e meu programa tem bastante muito eficaz desistido. Este é o fim do programa. Ele quebrou, ele caiu. Então não era muito, mas eu realmente fez aprender um pouco a partir desta pouca experiência. O que aprendi? Bem, o meu programa falha praticamente imediatamente. Meu programa trava em uma chamada para strcmp, mas eu Não temos quaisquer variáveis ​​locais na minha programa no momento em que ele trava. Então, o que string, ou cordas, eu poderia ser comparando. Se eu não tenho qualquer local, variáveis, você pode supor que eu have-- lá talvez é uma variável global, o que poderia ser verdade. Mas geralmente, parece como eu estou comparando a algo que não existe. Então, vamos investigar que um pouco mais. Então, eu estou indo para limpar minha tela. Eu vou sair fora do Ambiente GDB por um segundo. E eu estou pensando, OK, então não há há variáveis ​​locais em meu programa. Eu me pergunto se talvez eu deveria passar em uma seqüência de caracteres como um argumento de linha de comando. Então vamos testar isso. Eu não fiz isso antes. Vamos ver se talvez se eu executar este programa com um argumento de linha de comando que funciona. Huh, não há falha de segmentação. Ele só me disse que eu percebi isso. Então, talvez essa seja a solução aqui. E, de fato, se eu voltar e olhar para o código-fonte real para buggy1.c, parece que o que estou fazendo é Eu estou fazendo uma chamada à strcmp sem verificar se, de facto, argv [1] existe. Esta é realmente a código-fonte para buggy1.c. Então, o que eu realmente preciso fazer aqui para corrigir o meu programa, Supondo que eu tenho a apresentar na frente de mim, é apenas para adicionar uma seleção para fazer certo que argc é igual a 2. Assim, neste exemplo, mais uma vez, como eu disse, é um pouco artificial, certo? Você geralmente não vai acidentalmente excluir seu código-fonte e depois tem que tentar e depurar o programa. Mas espero que, deu uma ilustração dos tipos de coisas que você poderia estar pensando em como você está depuração do seu programa. Qual é o estado de coisas aqui? O que fazer variáveis ​​I têm acesso a mim? Onde exatamente é o meu programa deixar de funcionar, em que linha, sobre o que chamada para qual função? Que tipo de pistas que isso me dar? E isso é exatamente o tipo de mentalidade que você deve ser se metendo quando você está pensando depurar seus programas. Eu sou Doug Lloyd. Este é CS50.