Como melhorar sua capacidade de depurar o código existente [fechado]
29
Uma tarefa comum no mundo do trabalho é lidar com códigos existentes, mas com erros. Quais são algumas dicas para melhorar suas habilidades como depurador?
Muitas vezes, é tentador dizer "ah, eu sei o que esse código está fazendo, tudo bem". Não faça isso. Teste todas as suposições e passe por tudo cuidadosamente.
+1. Absolutamente. Esteja preparado para se surpreender com a forma como algumas das coisas, você pensou que sabia, vão pregar peças em você.
aufather
funciona para mim :)
setzamora 13/10/10
3
Depurar o código de outras pessoas é um grande desperdício de tempo, destrói a produtividade, mas é assim que é. O único momento em que realmente faz sentido corrigir os erros de outras pessoas é quando elas saem. O que eu odeio odiar é passar por um código objetivamente ruim por um codificador sênior, depois ter que fazer uma pergunta para obter progresso oportuno e fazer uma palestra sobre como melhorar minhas habilidades em aprender a base de código existente. Ao contrário de estudar a mãe natureza, resolver estragos causados por humanos não é divertido. Pelo menos eu recebo minha resposta. A situação inversa não acontecerá, porque sou apenas melhor e deixo menos bugs.
Job
11
@ Job: ... ok? Você quis deixar esse comentário no post, talvez? :)
Adam Lear
Este! É tolice confiar cegamente em qualquer parte do seu código, se você estiver depurando um problema estranho e o código parecer bom.
13553 Dan
7
Teste incrementalmente .
Vá em profundidade primeiro no seu código e teste-o a partir do menor módulo, movendo-se gradualmente. Dessa forma, você não está sob muito estresse tentando descobrir onde o problema exatamente pode estar.
Isso também significa que isso afeta menos código de cada vez desde que você está se movendo de forma incremental ... como às vezes tive problemas em que consertei algo e isso levou a quebrar muitas outras coisas. Dou crédito ao meu chefe por isso, pois ele me ensinou isso quando eu errei.
Dividir e conquistar é uma boa abordagem. Tente identificar alguma entrada visível (entrada do usuário / evento de rede ...) e saída (log, saída para o usuário, mensagem de rede de saída ...) entre as quais o problema existe. Tente colocar impressões em pedaços consideráveis ou pontos significativos entre eles e tente diminuir onde o erro está no código.
Dividir e conquistar também pode funcionar muito bem em caso de regressões sobre o código controlado por versão. Encontre duas construções - uma onde funcione conforme o esperado, outra com a regressão. Reduza a diferença até que você fique com um monte de check-ins como possíveis suspeitos.
Em vez de corrigir erros binários, escreva testes no formato
Dado...
Quando...
Espero...
Para verificar o que você realmente sabe sobre o funcionamento do aplicativo e o que você considera verdadeiro.
A maioria dos IDEs facilita a extração de métodos e a geração de stubs de teste do xUnit. Faça uso disso.
Por que não polvilhar debuga? Porque depois que você terminar, você provavelmente terá que desfazer muito desse trabalho e excluir uma boa quantidade desses erros. Quando você escreve testes, sua depuração ajudará na prevenção e detecção de futuros bugs.
Absolutamente a depuração está na arte em si, especialmente na depuração do código de outras pessoas.
Gratzy 13/10/10
2
Como outros já disseram - não assuma nada. Isto é especialmente verdade se o código que você escreveu. Ao depurar código de outras pessoas, é mais provável que você diminua a velocidade porque o código é novo para você ou você não confia no codificador. Ao depurar seu próprio código, é muito fácil supor que você o escreveu corretamente, diminua a velocidade!
Para o processo real de depuração:
Escreva testes de unidade se eles ainda não existirem.
Adicione o log apropriado se ainda não existir.
Em seguida, use a depuração.
Adicionar os testes de unidade e registrar primeiro mais eficientemente do que usar o depurador primeiro. Você também tem a vantagem de ter os testes de unidade para ajudar a não introduzir bugs futuros, e o registro ajudará as sessões de depuração no futuro.
Antes de passar por cima de um pequeno pedaço de código, verifique se você pode determinar com precisão o resultado. Isso tende a parecer irreal e não assume nada (que eu votei em BTW), mas à medida que você ganha experiência, isso pode ajudar a restringir onde procurar.
Isso pode parecer trivial, mas aprenda as nuances do seu depurador e as teclas de atalho. Às vezes, os depuradores podem ser lentos o suficiente para que sua mente se pergunte quando está passando. Se você consegue acompanhar a máquina e não está andando por aí, isso pode ajudar.
Se você pode modificar o código durante a depuração:
considere afirmar condições pré e pós. Às vezes, você pode passar por cima, em vez de entrar no código.
para declarações if com expressões complicadas, considere algo (alguns podem desaprovar isso, mas funciona para mim)
gostar:
bool isLessThan5 = a < 5;
bool isGreaterThan10 = a > 10;
if ( isLessThan5 || isGreaterThan10 )
{
// more code here
}
ao invés de:
if ( a < 5 || a > 10 )
{
// more code here
}
Nos casos em que você não pode depurar tudo, por qualquer motivo, aprenda a "pato de borracha" com um colega de trabalho. Às vezes, o ato de explicar lança luz. (ok, talvez isso não esteja exatamente no tema das perguntas, mas acho que está perto o suficiente para merecer menção)
A nomeação de subcondições precisa de um passo a mais, ou seja, a refatoração dos nomes quando você descobrir para que serve a condição. Pode ser if (tooCloseToHydrant || overTheBrink) { que você aprenda mais tarde.
1
Duas coisas, baseadas em passar a maior parte dos últimos 22 anos mantendo o código que outras pessoas escreveram.
Entenda os tipos de bugs que você costuma escrever.
Por exemplo, sou um codificador muito meticuloso, portanto, uma vez que meu código é compilado, ele geralmente fica livre de bugs triviais. Então, meus erros tendem a ser coisas complicadas e estranhas, como deadlocks de threads. Por outro lado, tenho um amigo que escreve principalmente bugs triviais - ponto e vírgula no final do C ++ para loops, para que a próxima linha seja executada apenas uma vez, esse tipo de coisa.
Não assuma que outras pessoas escrevem os mesmos tipos de erros que você.
Não sei quantas vezes perdi tempo puxando as grandes armas de depuração, assumindo que um bug era meu tipo de coisa realmente sutil e estranha, apenas para que meu amigo olhasse por cima do ombro e dissesse: "Você notou isso a mais?" ponto e vírgula?" Depois de anos disso, primeiro busco as frutas triviais e baixas quando observo o código de outras pessoas.
@ Thorbjørn: Se eu assumi a propriedade do código, às vezes faço isso para melhorar a legibilidade, mas não para encontrar erros de digitação. Idéia interessante!
Bob Murphy
você não precisa confirmar, apenas veja o que acontece. Posso altamente recomendável aplicar uma política que exige código para ser reformatado - de preferência automaticamente - quando o check-in.
@ Thorbjørn: Eu adoraria fazer isso. O que você recomenda como um "prettifier" de código? Eu trabalho principalmente no Linux e Mac.
Bob Murphy
Eu uso o Eclipse disponível nos dois locais, e o editor Java possui uma ação chamada Save, na qual é possível especificar o que deve acontecer cada vez que o arquivo é salvo. Aqui uma das opções é formatar a fonte. Como somos uma equipe pequena, não investiguei mais a respeito. Equipes mais experientes permitem ganchos de pré-confirmação nos sistemas de controle de origem, permitindo que uma confirmação de origem seja rejeitada se for formatada incorretamente. Muito eficiente.
1
Conheça suas ferramentas. Por exemplo, o depurador do Visual Studio possui um recurso impressionante chamado TracePoints que são como pontos de interrupção, mas, em vez de interromper seu código, insere uma instrução de rastreamento na saída de depuração.
É altamente recomendável ler livros ou fazer uma aula sobre como usar seu depurador. Tomei algumas aulas e li alguns livros de John Robbins que fizeram uma grande diferença na minha eficácia como depurador.
Entenda funcionalmente o que o código está tentando fazer. Se você não conhece a imagem completa (todos os casos de teste que esse código deve passar), é difícil depurar corretamente sem introduzir novos bugs
Escreva testes de unidade automatizados e outros tipos de integração e testes funcionais.
Quanto mais testes automatizados você tiver, menos tempo precisará gastar em um depurador.
Além disso, um bom design - princípios SOLID. Se você estiver escrevendo classes pequenas e focadas e favorecendo a composição sobre a herança, eliminando a duplicação etc., seu código sempre será mais fácil de depurar.
Acho que o código bem projetado produz um conjunto diferente de erros que o código não foi bem projetado. De um modo geral, o código bem projetado produz bugs que são mais fáceis de encontrar, reproduzir e corrigir.
A exceção (e sempre existe uma) é o código multithreading :-)
Se você o reduziu a uma região pequena, mas ainda não consegue identificar o erro, tente a opção 'view code + assembly' do seu depurador. Sabendo o ASM suficiente para dizer "deve haver um ramo aqui" ou "por que ele está apenas copiando a palavra mais baixa?" geralmente identifica o erro de codificação.
Os slides do livro estão disponíveis on-line, mas acho que o livro em si é mais fácil de ler.
O livro ajudará você a começar e a pensar mais cientificamente sobre a depuração, mas não substitui a prática. Você pode precisar escrever e depurar por 10 anos antes de ver uma melhoria de ordem de magnitude em seu desempenho. Ainda me lembro de ter ficado de queixo caído na Sun vendo os desenvolvedores seniores, que programam para Unix há 30 anos, encontrarem multithreading obscuros ou erros paralelos em minutos. Experiência importa!
Respostas:
Não assuma nada
Muitas vezes, é tentador dizer "ah, eu sei o que esse código está fazendo, tudo bem". Não faça isso. Teste todas as suposições e passe por tudo cuidadosamente.
fonte
Teste incrementalmente .
Vá em profundidade primeiro no seu código e teste-o a partir do menor módulo, movendo-se gradualmente. Dessa forma, você não está sob muito estresse tentando descobrir onde o problema exatamente pode estar.
Isso também significa que isso afeta menos código de cada vez desde que você está se movendo de forma incremental ... como às vezes tive problemas em que consertei algo e isso levou a quebrar muitas outras coisas. Dou crédito ao meu chefe por isso, pois ele me ensinou isso quando eu errei.
fonte
Dividir e conquistar é uma boa abordagem. Tente identificar alguma entrada visível (entrada do usuário / evento de rede ...) e saída (log, saída para o usuário, mensagem de rede de saída ...) entre as quais o problema existe. Tente colocar impressões em pedaços consideráveis ou pontos significativos entre eles e tente diminuir onde o erro está no código.
Dividir e conquistar também pode funcionar muito bem em caso de regressões sobre o código controlado por versão. Encontre duas construções - uma onde funcione conforme o esperado, outra com a regressão. Reduza a diferença até que você fique com um monte de check-ins como possíveis suspeitos.
fonte
Em vez de corrigir erros binários, escreva testes no formato
Para verificar o que você realmente sabe sobre o funcionamento do aplicativo e o que você considera verdadeiro.
A maioria dos IDEs facilita a extração de métodos e a geração de stubs de teste do xUnit. Faça uso disso.
Por que não polvilhar debuga? Porque depois que você terminar, você provavelmente terá que desfazer muito desse trabalho e excluir uma boa quantidade desses erros. Quando você escreve testes, sua depuração ajudará na prevenção e detecção de futuros bugs.
fonte
Continue depurando. Se você depurar muito, vai melhorar.
fonte
Como outros já disseram - não assuma nada. Isto é especialmente verdade se o código que você escreveu. Ao depurar código de outras pessoas, é mais provável que você diminua a velocidade porque o código é novo para você ou você não confia no codificador. Ao depurar seu próprio código, é muito fácil supor que você o escreveu corretamente, diminua a velocidade!
Para o processo real de depuração:
Adicionar os testes de unidade e registrar primeiro mais eficientemente do que usar o depurador primeiro. Você também tem a vantagem de ter os testes de unidade para ajudar a não introduzir bugs futuros, e o registro ajudará as sessões de depuração no futuro.
fonte
Antes de passar por cima de um pequeno pedaço de código, verifique se você pode determinar com precisão o resultado. Isso tende a parecer irreal e não assume nada (que eu votei em BTW), mas à medida que você ganha experiência, isso pode ajudar a restringir onde procurar.
Isso pode parecer trivial, mas aprenda as nuances do seu depurador e as teclas de atalho. Às vezes, os depuradores podem ser lentos o suficiente para que sua mente se pergunte quando está passando. Se você consegue acompanhar a máquina e não está andando por aí, isso pode ajudar.
Se você pode modificar o código durante a depuração:
gostar:
ao invés de:
Nos casos em que você não pode depurar tudo, por qualquer motivo, aprenda a "pato de borracha" com um colega de trabalho. Às vezes, o ato de explicar lança luz. (ok, talvez isso não esteja exatamente no tema das perguntas, mas acho que está perto o suficiente para merecer menção)
fonte
if (tooCloseToHydrant || overTheBrink) {
que você aprenda mais tarde.Duas coisas, baseadas em passar a maior parte dos últimos 22 anos mantendo o código que outras pessoas escreveram.
Entenda os tipos de bugs que você costuma escrever.
Por exemplo, sou um codificador muito meticuloso, portanto, uma vez que meu código é compilado, ele geralmente fica livre de bugs triviais. Então, meus erros tendem a ser coisas complicadas e estranhas, como deadlocks de threads. Por outro lado, tenho um amigo que escreve principalmente bugs triviais - ponto e vírgula no final do C ++ para loops, para que a próxima linha seja executada apenas uma vez, esse tipo de coisa.
Não assuma que outras pessoas escrevem os mesmos tipos de erros que você.
Não sei quantas vezes perdi tempo puxando as grandes armas de depuração, assumindo que um bug era meu tipo de coisa realmente sutil e estranha, apenas para que meu amigo olhasse por cima do ombro e dissesse: "Você notou isso a mais?" ponto e vírgula?" Depois de anos disso, primeiro busco as frutas triviais e baixas quando observo o código de outras pessoas.
fonte
Conheça suas ferramentas. Por exemplo, o depurador do Visual Studio possui um recurso impressionante chamado TracePoints que são como pontos de interrupção, mas, em vez de interromper seu código, insere uma instrução de rastreamento na saída de depuração.
É altamente recomendável ler livros ou fazer uma aula sobre como usar seu depurador. Tomei algumas aulas e li alguns livros de John Robbins que fizeram uma grande diferença na minha eficácia como depurador.
fonte
Entenda funcionalmente o que o código está tentando fazer. Se você não conhece a imagem completa (todos os casos de teste que esse código deve passar), é difícil depurar corretamente sem introduzir novos bugs
fonte
Escreva testes de unidade automatizados e outros tipos de integração e testes funcionais.
Quanto mais testes automatizados você tiver, menos tempo precisará gastar em um depurador.
Além disso, um bom design - princípios SOLID. Se você estiver escrevendo classes pequenas e focadas e favorecendo a composição sobre a herança, eliminando a duplicação etc., seu código sempre será mais fácil de depurar.
Acho que o código bem projetado produz um conjunto diferente de erros que o código não foi bem projetado. De um modo geral, o código bem projetado produz bugs que são mais fáceis de encontrar, reproduzir e corrigir.
A exceção (e sempre existe uma) é o código multithreading :-)
fonte
Se você o reduziu a uma região pequena, mas ainda não consegue identificar o erro, tente a opção 'view code + assembly' do seu depurador. Sabendo o ASM suficiente para dizer "deve haver um ramo aqui" ou "por que ele está apenas copiando a palavra mais baixa?" geralmente identifica o erro de codificação.
fonte
Confira o livro muito valioso Por que os programas falham: um guia para depuração sistemática , de Andreas Zeller. Ele apresentará muitas técnicas, teorias e ferramentas, algumas das quais estão na vanguarda da pesquisa.
Os slides do livro estão disponíveis on-line, mas acho que o livro em si é mais fácil de ler.
O livro ajudará você a começar e a pensar mais cientificamente sobre a depuração, mas não substitui a prática. Você pode precisar escrever e depurar por 10 anos antes de ver uma melhoria de ordem de magnitude em seu desempenho. Ainda me lembro de ter ficado de queixo caído na Sun vendo os desenvolvedores seniores, que programam para Unix há 30 anos, encontrarem multithreading obscuros ou erros paralelos em minutos. Experiência importa!
fonte