Qual é o benefício de evitar o uso de um depurador?


101

Ao longo da minha carreira, notei que alguns desenvolvedores não usam ferramentas de depuração, mas verificam códigos errados para descobrir qual é o problema.

Embora muitas vezes ser capaz de encontrar rapidamente erros no código sem um depurador seja uma boa habilidade, parece ser menos produtivo gastar muito tempo procurando problemas quando um depurador encontraria facilmente pequenos erros como erros de digitação.

É possível gerenciar um complexo sem um depurador? É aconselhável? Quais benefícios existem com o uso de " depuração psíquica ?"


19
Olá Jonathan, eu revisei sua pergunta para evitar as armadilhas de um discurso retórico e manter a pergunta em aberto: acho que - como está agora - é uma pergunta decente e respondível.

Exemplo: considere um código a = 6/3., Em vez de erro de digitação, você digitou a = 6/2.. Agora, você está pesquisando no nível mnemônico., As instruções ADD, JMP e, em seguida, descobre que houve uma iteração extra em vez de 2., e percebe que o divisor possui um erro de digitação errado. Agora você pode deduzir como é ridículo usar sempre um depurador.
EAGER_STUDENT

Respostas:


153

O que parece adivinhar de fora costuma ser o que chamo de "depuração em sua mente". De certa forma, isso é semelhante à capacidade dos mestres de jogar xadrez sem olhar para um tabuleiro de xadrez.

É de longe a técnica de depuração mais eficiente que eu conheço, porque não requer um depurador. Seu cérebro explora vários caminhos de código ao mesmo tempo, produzindo um retorno melhor do que você poderia obter com um depurador.

Eu não estava consciente dessa técnica antes de entrar brevemente no mundo da programação competitiva , onde usar um depurador significava perder segundos preciosos. Após cerca de um ano de competição, comecei a usar essa técnica quase exclusivamente como minha linha de defesa inicial, seguida pelo log de depuração, com o uso de um depurador real no terceiro lugar distante. Um efeito colateral útil dessa prática foi que comecei a adicionar novos bugs em um ritmo mais lento, porque a "depuração na minha mente" não parou quando escrevi um novo código.

É claro que esse método tem suas limitações, devido principalmente às limitações da mente em visualizar vários caminhos através do código. Aprendi a respeitar essas limitações da minha mente, recorrendo a um depurador para corrigir bugs em algoritmos mais avançados.


27
+1 Acho que "programação por adivinhação" é uma frase carregada. Não há substituto para o pensamento. O que o OP não explica é a eficácia da "adivinhação". Minha dúvida é que é pura adivinhação (isto é, espaguete na abordagem da parede), mas usando raciocínio dedutivo. Depuradores têm seu lugar, mas não são uma panacéia para raciocínio dedutivo e simplesmente para entender o código.
Bill

8
@DJClayworth Isso não é totalmente exato: às vezes, tentar usar um depurador é uma má escolha, mesmo se você tiver um bom depurador à sua disposição: você acaba perdendo muito tempo sem realizar muito. Um caso que imediatamente me vem à cabeça é resolver problemas de concorrência; os outros estão depurando algoritmos recursivos com altos fatores de ramificação, alguns algoritmos de programação dinâmica e rotinas de serviço de interrupção de hardware. É claro que é bobagem não usar um depurador quando você realmente precisa dele, mas decidir quando você começa a precisar de um depurador é uma opção altamente individual.
precisa saber é o seguinte

9
+1, embora eu ache um depurador inestimável para certos tipos de bug (particularmente em algoritmos mais complexos), na verdade não há substituto para simplesmente entender bem o código #
Chris Browne

7
@DJClayworth Fui deliberadamente a favor de uma afirmação mais forte do que "algumas ocasiões em que não usar um depurador é melhor": meu breve encontro com a programação competitiva me ensinou que buscar instintivamente um depurador não é o comportamento mais eficiente para mim . Atualmente, começo (1) relendo rapidamente o código e (2) examinando o rastreamento de depuração (quando disponível) antes (3) de ir para um depurador. Em muitos casos, a terceira etapa é desnecessária, porque identifico o problema nas etapas (1) ou (2), escrevo um teste de unidade que reproduz o problema e codifique uma correção, tudo sem o uso de um depurador.
precisa saber é o seguinte

10
Eu acho que o que você realmente quer dizer é que um programador deve ter uma sequência de depuração , em vez de clicar no botão mágico "encontrar bug". Um depurador é uma ferramenta extremamente poderosa, mas você não aciona a serra elétrica para aparar as sebes.
Spencer Rathbun

41

Quanto mais eu conheço uma base de código, menos preciso de um depurador (mas ainda assim verifico o erro relatado, é uma pista importante em qualquer raciocínio).

É uma boa ferramenta para entender algum comportamento dinâmico de pequena a média complexidade, mas geralmente descubro que ele me concentra nos detalhes, e não na imagem maior. E depois de um tempo, é aí que estão os problemas: em interações de escopo mais amplo, cujo comportamento dinâmico tende a ser mais facilmente compreensível com outras ferramentas (registro de entradas e saídas nos limites do módulo, por exemplo).


35

Eles podem não ser maus programadores, mas provavelmente são solucionadores de problemas terrivelmente ineficientes.

Tenho a tendência de seguir os conselhos de Depuração: As 9 regras indispensáveis ​​para encontrar até os problemas mais difíceis de software e hardware (David Agans), e este se enquadra diretamente na orientação de "Pare de pensar e procurar"


12
Eu discordo, mas não vou votar. Como delnan diz, se você pode entender o que o código está fazendo, pode ser mais rápido identificar o que está fazendo de errado do que percorrer o depurador e tentar descobrir quando ele dá errado. Dito isto, um desenvolvedor que se recusa a usar um depurador quando não consegue identificar o problema ao ler o código está cometendo um grande erro.

O @Mark mais o bônus adicional de diagnosticar incorretamente o problema e conectar um novo defeito.
Keith traz

11
@ Mark Bannister - Entendo o que você está dizendo. Deixe-me alterar isso para, se você estiver procurando o problema no código por mais de 15 minutos, desista e use o depurador e não seja teimoso.
JohnFx

9
Eu acho que um bom programador não deve depender do depurador. Isso não deve impedi-lo de usar um imediatamente (quando disponível), uma vez que seu insight falhar - ou periodicamente, para garantir que seu insight ainda esteja no caminho certo ...
comingstorm

1
@mark, a menos que você esteja trabalhando em uma base de código muito pequena, acho impossível entender todas as linhas de código. 95% dos meus erros atuais são resolvidos da maneira que você descreve, mas os mais complicados são onde você precisa do depurador.
precisa saber é o seguinte

31

Qualquer trabalho exige o uso das ferramentas certas da maneira certa. Se você tiver um depurador, use-o para ver o que realmente está acontecendo. A maioria dos erros é causada por suposições.

Eu trabalhei com desenvolvedores que se recusam a usar depuradores porque sabiam melhor. A resposta clássica que recebi uma vez foi 'o acidente não está sendo causado por mim, passei o dia todo inspecionando o código [onde estava travando] e não há nada errado'. (E o valor nulo que foi lido no banco de dados?) O chefe parecia pensar que era uma ótima resposta, mas o cliente não.

Saí dessa equipe o mais rápido que pude. Seu objetivo era embelezar o trabalho e transformar um simples problema de 10 minutos em um problema que parecia o dia todo ocupado.


18
+1 "A maioria dos erros são causados ​​por suposições" são palavras muito sábias
ZJR 23/01/12

15
Presumo que todos os erros sejam causados ​​por suposições. (? Veja o que eu fiz lá = P)
dan_waterworth

4
@ZJR: É por assertisso que é tão bom. Verifique suas suposições. Verifique-os frequentemente.
Zan Lynx

@dan_waterworth: Não é verdade. Por um lado, poderia ser um erro de digitação.
Thomas Eding

13

Seu melhor guia para a prática da depuração é o livro de Steve McConnel, Code Complete . O capítulo 23 aborda a depuração em detalhes, e eu irei destilar alguns pontos.

  1. Compreender o problema é importante e o uso do depurador não é um substituto para ele.
  2. Adivinhar é uma péssima abordagem para depuração. Se seus colegas estão realmente usando suposições, em vez de pensar no problema, eles estão fazendo um trabalho ruim. Adivinhação significa colar instruções de impressão aleatórias no código e esperar encontrar algo útil.
  3. Se seus colegas realmente não sabem como usar um depurador (em vez de optar por não usá-lo), então sim, eles são incompetentes, assim como alguém que não conhece a sintaxe do idioma que deveria usar.

2
Embora eu concorde com você na maior parte do seu post, acho incompetente injusto. É possível desenvolver sem o uso de um depurador, é apenas ineficiente. Algumas pessoas aprendem sobre depuradores antes de outras!
precisa saber é o seguinte

Eu não jogaria casualmente palavras como "incompetente". Conheço alguém que depura inteiramente com declarações impressas e ninguém mais chega perto de dar a contribuição que ele faz.
Mike Dunlavey

2
@MikeDunlavey Essa pessoa sabe como usar um depurador e escolhe não usá-lo? Bem. Se eles não sabem, eu mantenho minha afirmação.
DJClayworth

2
Fique como quiser, poderá chegar facilmente um momento em que esse adjetivo poderá ser aplicado a você. Então você vai entender - é coisa de escola.
precisa saber é o seguinte

9

Difícil de dizer. A depuração por suposição pode funcionar se você já tiver uma idéia sobre o que é o erro (valor incorreto passado para uma função de biblioteca, possivelmente SQL inválido, etc.). Admito que às vezes o faço quando o erro parece pequeno ou óbvio, como "buffer de caracteres muito pequeno" - o rastreamento da pilha mostra a linha em que houve falha e não preciso de um depurador para resolvê-lo.

Fazer isso o tempo todo pode ser contraproducente e, se os primeiros "palpites" falharem, adivinhar provavelmente é a estratégia de solução de problemas errada e um depurador real deve ser chamado. Normalmente, eu diria que não há absolutamente nada de errado em usar o depurador .

Dito isto, trabalhei com ferramentas e ambientes em que o depurador era tão difícil de funcionar corretamente, ou tão mínimo e inútil que a adivinhação era, infelizmente, frequentemente uma abordagem melhor. Eu trabalhei com algumas ferramentas proprietárias que nem tinham depuradores adequados. Suponho que seja possível que, se uma pessoa trabalhe nesses ambientes por muito tempo, acabe perdendo a confiança nos depuradores e confiando apenas na abordagem de adivinhação.


8

Estou surpreso que a discussão sobre este tópico não tenha mencionado "teste de unidade".

Como eu faço o desenvolvimento orientado a testes, não passo muito tempo no depurador. Há 10 anos, eu costumava percorrer o depurador:

  1. Depois de escrever um pedaço de código para garantir que funcionou e
  2. Quando recebi um relatório de bug para tentar diagnosticar o problema

O que descobri após 10 anos de desenvolvimento orientado a testes é que sou muito mais produtivo como programador se:

  1. Escrevo testes de unidade antes de escrever o código para garantir que o escrevi corretamente
  2. Escrevo testes de unidade imediatamente após receber um relatório de erro para tentar duplicar e detalhar o problema.

Permitir que o computador execute o código e valide o resultado é milhares de vezes mais rápido do que eu consigo pensar ou percorrer o código para validar mentalmente os resultados e não cometer erros.

Eu ainda tenho que avançar no depurador ocasionalmente e ainda estou analisando mentalmente o código ... mas apenas raramente, e principalmente por códigos muito complicados.


+1 Geralmente, é mais rápido adicionar uma declaração de impressão e executar novamente o teste e usar um depurador.
Winston Ewert

@ winston - geralmente é mais rápido acionar o depurador do que escrever várias instruções de impressão até encontrar o local do código problemático. Tudo depende. Problemas simples geralmente são resolvidos mais rapidamente da maneira que você descreve, mas problemas complexos são onde você precisa do depurador. Ser capaz de usar ambos é melhor do que seguir estritamente qualquer princípio absoluto.
Wobily_col

7

Pessoalmente, tento minimizar o uso de um depurador:

  • usando verificadores estáticos e opções de compilador semelhantes, que sugerem possíveis fontes de erros apenas analisando o código
  • escrever código com o menor número possível de efeitos colaterais , no estilo mais funcional possível, eliminando o estado mutável sempre que possível
  • escrever testes de unidade com a granularidade mínima razoável
  • não engolir exceções

É claro que todos cometem erros, portanto, mesmo ao compor programas dessa maneira, se um teste falhar, eu uso o depurador para inspecionar o valor de uma expressão intermediária. Mas, aderindo aos princípios acima, o defeito é mais fácil de localizar e a depuração não significa um processo indeterminado e doloroso.


6

Use o depurador sempre que possível. O depurador simplesmente resolverá o problema (veja, não checamos esse valor) ou fornecerá uma grande quantidade de contexto útil ao analisar o código relevante (uau, a pilha está totalmente bagunçada, eu vou seja um problema de estouro de buffer).


5

A depuração é uma ferramenta muito útil para inspecionar o estado dos objetos e variáveis ​​no seu código em tempo de execução.

Como mencionado anteriormente nas respostas acima, a depuração é extremamente útil, mas há alguns casos em que é limitada.

Na minha experiência, acho que usar o depurador é muito útil, pois ajuda a revelar suposições falsas que eu estava fazendo sobre o estado do meu código. Algumas pessoas não são tão astutas ao ler o código para encontrar um bug; portanto, a depuração pode ajudar a revelar suposições falsas que você ou outro desenvolvedor fez sobre o estado do código.

Talvez você espere que um parâmetro nunca seja nulo quando passado para um método, portanto nunca verifique esse caso e continue o método como se esse parâmetro nunca fosse nulo. A realidade é que o parâmetro acabará sendo nulo em algum momento, mesmo se você definir como pré-condição o método para que o parâmetro nunca seja nulo. Isso sempre vai acontecer.

Em contraste com a utilidade dos depuradores nos exemplos acima mencionados, acho difícil e um pouco inútil usar quando o multi-threading (ou seja, simultaneidade, processamento assíncrono) está envolvido. Isso pode ajudar, mas é fácil perder sua orientação no nevoeiro multithread quando os pontos de interrupção do depurador estão sendo atingidos em um thread no ponto A e um thread completamente separado no ponto B. O desenvolvedor é forçado a empurrar o novo ponto de interrupção " processo de pensamento "no topo da" pilha "de seu cérebro e orientar-se para o código no ponto do novo ponto de interrupção. Depois que a relevância do ponto de interrupção B diminui, o desenvolvedor volta ao primeiro ponto de interrupção e precisa lembrar o que estava procurando antes do gatilho do ponto de interrupção B. Sei que essa pode ser uma explicação confusa,

Além disso, a imprevisibilidade do código simultâneo pode distrair ainda mais o desenvolvedor na depuração de código simultâneo.

Em conclusão, na minha opinião honesta:

  • Depuração quando a simultaneidade é usada = tendência aumentada para perder o foco do "padrão de pensamento de depuração"

e

  • a qualquer momento = maior produtividade da depuração porque sua atenção não é interrompida por pontos de interrupção inesperados (inesperados devido às condições da corrida).

2
+1 por abordar a questão da depuração em ambientes simultâneos, onde a utilidade dos depuradores tradicionais geralmente diminui para quase zero.
precisa saber é o seguinte

4

Eu acho que eles estão sendo um pouco hardcore demais. Pessoalmente, quando encontro um bug, checo novamente o código, tento rastreá-lo na lógica do programa, porque isso às vezes me ajuda a descobrir outros problemas ou efeitos colaterais mais fáceis do que usar o depurador e corrigir o bug onde ele se manifesta. .

Mesmo quando acho que já o peguei, geralmente depuro para ter certeza de que estou certo. Quando o problema é um pouco mais complexo, acredito que a depuração é absolutamente essencial.

Também ... apenas minha opinião, mas não há desculpa para não tirar uma vantagem decente das ferramentas que um IDE moderno pode trazer para a mesa. Se isso o ajudar a concluir seu trabalho mais rapidamente e de maneira mais confiável, você deve usá-lo.


4

Odeio generalizar, mas muitos programadores que conheci pensam que há apenas uma maneira de resolver um problema (o caminho deles). É fácil assumir que todos os testes possíveis foram pensados. Uma perspectiva diferente pode ser muito valiosa.

A programação por tentativa e erro pode apresentar novas abordagens excelentes e capturar coisas que outras pessoas perderam.

A desvantagem, geralmente leva muito mais tempo.


4

Erm, isso depende da pessoa. Pessoalmente, eu não uso muito esses depuradores. Ao programar microcontroladores, basicamente uso LEDs ou gravando dados nas EEPROMs para "depurar" o código nele. Eu não uso JTAG.

Ao programar software para PCs ou servidores, costumo usar log e muita saída do console. Para linguagens no estilo C, uso diretivas de pré-processador e, em Java, usei níveis de log.

Como não uso depuradores, você diria que estou fazendo algo errado? São os trabalhos dos editores, para me mostrar onde tenho erros sintáticos e, quando há um erro lógico, só preciso executar testes.


4

Há uma diferença entre não precisar usar um depurador e não saber (ou recusar) usar um depurador. O depurador é apenas uma das muitas ferramentas para usar no rastreamento e correção de bugs. Eu trabalhei com desenvolvedores que podem entender isso de cabeça e outros que pensam que podem.

A melhor combinação é escrever seu código para facilitar o teste através de testes de unidade e registrar os erros. Então você espera que não precise olhar para os logs ou usar o depurador. É como comprar seguro. Esperamos que você nunca precise usá-lo, mas depois de encontrar um bug que não pode ser resolvido revisando novamente o código, é tarde demais para adicionar manipulação / registro de erros adequados, testes de unidade ou aprender a usar um depurador.

Diferentes ferramentas / plataformas favorecem diferentes técnicas de depuração (depurador, registro, testes de unidade etc.) Desde que um desenvolvedor esteja familiarizado com algumas das técnicas de sua plataforma / ferramenta, além de apenas verificar novamente o código, elas podem ser um desenvolvedor habilidoso, mas se eles tiverem apenas um truque no que diz respeito à depuração, acabarão encontrando um bug que não conseguem encontrar ou corrigir.


4

Muitas respostas, mas nenhuma menção sobre Heisenbug ?!?!

Heisenbugs ocorrem porque tentativas comuns de depurar um programa, como inserir instruções de saída ou executá-lo em um depurador, geralmente modificam o código, alteram os endereços de memória das variáveis ​​e o tempo de sua execução.

Eu uso o depurador, apenas no pior dos casos (para erros difíceis de encontrar). Além disso, de acordo com as práticas recomendadas de que muitos desenvolvedores / testadores aclamados estão falando, é bom testar o código da unidade completamente. Dessa forma, você pode cobrir a maioria dos problemas e, portanto, não haveria necessidade de usar o depurador.


3

Li recentemente um argumento contra a depuração do depurador aqui (ou foi o StackOverflow?). Você deve ter casos de teste em relação ao seu código. Se seus testes forem aprovados, sua depuração provavelmente não irá exercer o erro (suposição: você irá depurar com dados semelhantes aos dados de teste).

Por outro lado, o registro é obrigatório. Se você passar nos testes e implantá-lo na produção, poderá descobrir que possui um erro. A evidência do bug é de algo que aconteceu no passado. ou seja, alguém diz: "Como isso chegou lá?" Se você não tiver bons registros, nunca encontrará a causa. Até mesmo um depurador pode não ter utilidade nesse momento, porque você não sabe como os dados pareciam que realmente exercitavam o bug. Você precisa ser capaz de depurar o aplicativo dos logs.

Infelizmente, estou parafraseando um pouco e posso estar fazendo um argumento em desacordo com o argumento original. Em particular, a posição de "Existem importantes auxiliares de depuração para dedicar tempo ao desenvolvimento" pode ser ortogonal à importância dos depuradores. Mas a parte sobre a dificuldade em definir o estado do sistema em uma configuração que torna a depuração útil para encontrar bugs me pareceu algo para se pensar.


3

Com bons testes de unidade e exceções que fornecem o backtrace, você raramente precisa usar um depurador.

A última vez que usei uma depuração foi quando obtive um arquivo principal em algum aplicativo herdado.

Eu estou sendo um "servo debbuger" ou esses caras estão sendo "muito hardcore"?

Nem. Eles são apenas pessoas que gostam de tornar sua vida mais difícil do que deveria ser.


2

A depuração é apenas uma ferramenta que um bom desenvolvedor deve usar eficientemente.

Certamente, às vezes, você pode saber de cor onde o erro pode estar se você souber a base de código. Mas você também pode perder um dia ou semana inteiro para encontrar um bug irritante apenas olhando o código.

Em linguagens tipadas dinamicamente sem algum tipo de depuração (mesmo que seja apenas despejando valores no console), adivinhar às vezes se torna impossível.

Portanto, para responder à sua pergunta - talvez eles sejam programadores brilhantes, mas suas habilidades para solucionar problemas e sua proficiência na caça de bugs são ruins.


2

Depende do escopo de um problema. Se o programa é pequeno e as coisas estão bem divididas, você provavelmente pode descobrir isso olhando. Se o programa tiver 4,5 milhões de linhas de código desenvolvidas por uma equipe de mais de 100 pessoas ao longo de vários anos, será impossível detectar certos bugs.

O em questão no referido programa (em C) foi uma substituição de memória. O depurador com um ponto de interrupção de memória identificou a linha de código incorreta assim que o bug apareceu. Mas, neste caso, não há como alguém ter lido e retido todos os 4,5 milhões de linhas de código para identificar o ponto em que alguém escreveu além de sua matriz (além disso, eles precisariam conhecer o layout de tempo de execução da memória para o estado do programa gigantesco cerca de 10 minutos em um longo período de entradas para chegar a esse ponto).

O ponto principal é que: em pequenos programas ou coisas altamente modulares, você pode fugir sem um depurador. Se o programa for realmente grande e complexo, o depurador poderá economizar muito tempo. Como outros já disseram, é uma ferramenta e possui situações em que se destaca acima de qualquer outro método e outras em que não é a melhor escolha.


0

Se o erro ocorrer no computador de um cliente ou em um computador cujo ambiente seja muito diferente do seu, a configuração de um depurador / depurador remoto é complicada. Portanto, para o dia frio em que você recebe um bug do campo, a resposta de 'mas ... eu não tenho um depurador' não ajuda. Portanto, você precisa desenvolver um conjunto de habilidades para solucionar problemas e encontrar o bug apenas através da compreensão dos arquivos de código e log.


-1

Que bobagem: "Programadores reais não precisam de depuradores". Pode-se dizer que um programador de verdade não precisa de IDE, apenas me dê um bloco de notas e um lápis opaco. O depurador é uma ferramenta como qualquer outra que ajuda na produtividade.

Além disso, considere que nem todos os responsáveis ​​pelo código de depuração estão familiarizados com esse código em questão. Muitas vezes, os contratados entram em um ambiente em que apenas têm um ideal geral do que está acontecendo. Eles podem até receber uma descrição detalhada de um ambiente - ou um mapa de esquema de 20 anos e um guia para convenções de nomenclatura arcana (tente entender a diferença entre a tabela X1234 e a tabela X4312 com os campos F1, F2 e F3 [sim, lixo como este existe] quando você é novo), mas muitas vezes essa descrição está errada; caso contrário, por que existe um erro de "mistério".

Como alguém novo em um ambiente, você pode passar horas ou dias mapeando e conhecendo um grande banco de dados para uma área problemática que você pode corrigir e, em seguida, nunca mais precisará procurar novamente. Isso é um enorme desperdício de tempo e dinheiro. Se você tiver acesso ao depurador, veja o que está acontecendo, corrija-o e acabe em questão de minutos. Tudo isso "você não precisa de depuradores" hooey é apenas um baita elitista.


2
este homem de palha discurso não responde à pergunta feita, em nenhum lugar há uma declaração "Os programadores reais não precisam Depuradores"
mosquito
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.