O que fazer quando você tiver esgotado todos os caminhos para corrigir um erro


13

Eu sou um programador júnior (4 meses de experiência profissional até agora) trabalhando em um aplicativo móvel de plataforma cruzada (equipe de 1 pessoa - então sou eu mesmo).

Eu tenho um erro neste programa / aplicativo que é bastante grande (30 arquivos de cabeçalho diferentes, cada um com seu próprio arquivo cpp também). Eu tenho tentado rastrear exatamente o que está acontecendo com o bug e também corrigi-lo (até tentei usar alguns hacks para fazê-lo funcionar), mas com cerca de uma dúzia ou mais de soluções (idéias que tenho sobre o que está causando o problema) ) Eu descobri que nada me levou a rastrear exatamente o que é o bug ou corrigi-lo.

Você tem algum conselho para um programador júnior de algumas técnicas abrangentes (faça uma corrida, imprima todo o meu código em papel e passe por ele com uma caneta etc.) que eu poderia usar para me ajudar com esse bug?

Para dar um pouco mais de contexto ao meu bug; envolve a API Mosync de plataforma cruzada. Quando executo uma sequência específica de ações, a tela atual não redesenha (e parece) que a tela exibida anteriormente ainda está recebendo os eventos de ponteiro / pressionamento de tecla e não a tela atual.

Sequência específica:
- Tela de menu exibida - clique em "Mostrar botão anterior de pedidos"
- Tela anterior de pedidos exibida - clique em "Carregar arquivo", clique no botão de menu e abra a tela
Entrega - Tela de entrega exibida - clique no botão menu e abra a tela de
compra - Tela de compra exibida - Erro aqui, a entrada para esta tela não é exibida / não reagiu, o ListViews não rola, os botões não reagem aos cliques, as células do ListView não respondem aos cliques


Vou seguir o conselho, o bug é reproduzível 100% seguindo as mesmas etapas de cada vez, embora ainda seja muito difícil descobrir como os eventos do ponteiro estão sendo transmitidos e qual tela, devido ao fato de que isso faz parte da API. alcance (ou não saiba como).

Também adoraria ter um olhar diferente sobre o meu trabalho e apontar o erro, mas como eu disse que sou um time 1, meu chefe me dirige, ele é o dono da empresa e tem as idéias para um aplicativo, mas faz não sei c ++ ou quaisquer idiomas recentes (cobal? Eu acho que é tudo). Algum conselho sobre como obter um segundo par de olhos sem violar / exibir o código / propriedade intelectual da empresa?

... e não sair deste estágio remunerado não é uma opção, o contrato diz que, se eu sair antes dos 6 meses de um contrato de 12 meses, talvez eu deva pagar 30% do meu salário anual


6
É 100% reproduzível?

5
A resposta simples é envolver seus colegas . Em equipe, você resolverá isso em instantes.
Fattie

2
@ Joe - nem sempre. Por exemplo, erros no comportamento coletivo de múltiplos subsistemas de interação complexos, nos quais diferentes subsistemas foram construídos com visões sutilmente incompatíveis de suas funções, resultantes de ambiguidades não óbvias nas especificações - geralmente muito poucas pessoas têm o conhecimento detalhado de vários subsistemas e suas interações para poder diagnosticar esses problemas. Às vezes, você precisa conversar com todas as equipes e, quando duas pessoas começam a se chamar de idiotas, há uma chance de que estejam discutindo algo periférico relacionado às suposições incompatíveis.
Steve314

Mesclei suas contas. Você pode usar seu Yahoo OpenID para entrar. Também estou editando sua pergunta para incluir as informações que você postou como resposta.
Adam Lear

btw. Além da minha resposta abaixo, li na Wikipedia que o Mosync não é mais mantido?
Brad Thomas

Respostas:


19

Se você puder reproduzir o problema 100% do tempo, defina um ponto de interrupção na última etapa (o mais cedo possível). Se você percorrer toda a pilha de chamadas, tenho certeza de que você encontrará valores inesperados em algum lugar, ou algo que deve ser chamado, mas não é.

Editar:

E se você está sentado no limite de sua mente tentando consertar o erro e postando aqui esperando que você receba alguns conselhos claros, vá embora . Vá com calma e volte mais tarde (de preferência amanhã ou depois do fim de semana). Houve muitas vezes que passei o dia inteiro procurando uma solução para um problema específico, apenas para ir embora, voltar no dia seguinte com a cabeça limpa e encontrá-la em dez minutos.


4
e se, por qualquer motivo, você não puder usar um depurador, coloque algumas informações de rastreamento em torno do código que você acha que está falhando e registra suas chamadas de função em um arquivo de texto.

3
+1 para "Vá embora". É preciso muita experiência para saber quando sair de casa provavelmente será mais produtivo do que atacar o problema. Sua situação parece um bom lugar para começar a reunir essa experiência específica.
Mike Sherrill 'Recall Cat'

Se o seu software precisa de um ponto de interrupção para detectar o erro, seu cérebro também precisa. Isso economiza mais tempo do que se forçar e não se afastar.
Setzamora 23/05

Eu descobri que as funções de log que registram valores que podem ser relevantes geralmente são a melhor maneira de rastrear esse tipo de coisa. Formate as linhas de log com colunas bem organizadas, para que todas as alterações sejam destacadas. Chame essa função de registro frequentemente com um ID de onde é chamado. Você pode examinar o arquivo de log muito mais rapidamente do que pode monitorar as variáveis.
Loren Pechtel

10

Depurar é mais sobre isolar e entender exatamente qual é o problema (comparado à aplicação de uma correção)

Uma coisa a ter cuidado ao depurar é se você começar a perceber que está seguindo várias teorias, pois isso geralmente leva mais tempo e não elimina sistematicamente possíveis problemas.

Geralmente, a melhor maneira de depurar esse tipo de situação é a abordagem sistemática chata, dividindo seu sistema em pequenos pedaços e fazendo com que cada um funcione isoladamente e continue adicionando cada elemento da complexidade um por um até que ele se quebre. Então você isolou o problema exato. Dessa forma, pode parecer um pouco entediante e um trabalho mais inicial, mas remove variáveis ​​e mantém o cérebro saudável enquanto tenta depurar um software complexo.


5

Estas são apenas algumas das coisas que eu fiz no passado, obviamente elas não funcionam em todas as situações:

  1. Perceba que é apenas código, e em algum lugar existe um bug (não é apenas magia negra) que você PODE corrigir.
  2. Dar um tempo.
  3. Percorra o código muito lentamente, analisando cada etapa e certificando-se de entendê-lo e o que está fazendo, sem encobrir nada.
  4. Obtenha um segundo par de olhos para analisar o problema.
  5. Vá dormir e esqueça isso até amanhã (limpe sua cabeça), venha com uma nova perspectiva).
  6. Imprima seu código e analise cada linha, fazendo anotações nas margens, entendendo todas as implicações de cada linha
  7. Se não é um bug crítico, mas está causando erros que o usuário não precisa conhecer, eu (envergonhado, mas honestamente) prendi o bug e o engoli ! Se não é perigoso, e você não consegue encontrar a causa, às vezes você apenas a prende e não deixa o usuário saber que algo aconteceu. É tudo sobre ROI para o cliente e, às vezes, não vale a pena.
  8. Diga verbalmente ao bug que você o caçará e matará. Às vezes, ele foge. :-)

+1 por não ser magia negra!
Guy Sirton 23/05

Com todas as dependências complexas que adotamos hoje em nosso código, é magia negra. Mas você pode ficar bom nisso :)
Subu Sankara Subramanian

3

Eu geralmente tenho essa abordagem ao resolver bugs.

  1. Crie um bom passo a passo para reproduzir o bug
  2. Simplifique passo a passo
  3. Onde no código o erro ocorre? Como quais funções estão envolvidas?
  4. Qual o caminho que o código escolhe quando o bug ocorre, a cadeia de chamadas.
  5. Concentre-se no local, quando está tudo bem quando não está. Repita muito isso até encontrar exatamente o local em que o erro ocorre.
  6. Por que isso acontece?

Nesse ponto, geralmente fica claro o que aconteceu desde que eu aprendi muito no processo de foco no problema, então eu sei o que fazer. Ou tenho uma pergunta bastante focada que posso fazer em um fórum.

Então, tento corrigir o problema e use o passo a passo que você criou na etapa um para verificar se o bug foi corrigido.


3

Todos os conselhos anteriores são excelentes, e grande parte deles visa verificar suposições sobre o bug / erro e, em seguida, seguir um processo de depuração para localizar o erro (às vezes examinando o ambiente ao redor do bug e, outras vezes, diretamente no código).

Essa abordagem nem sempre funcionará, independentemente de depender de sua antiguidade ou experiência. Às vezes, você só precisa de outro par de olhos para o problema. Encontre alguém para revisar o problema ou a sessão de depuração com você - geralmente apenas conversando com o código o levará ao erro.


Eu concordo, que muitas vezes funcionou para mim.
Mike Dunlavey

1

Como outros disseram 1) ser capaz de reproduzi-lo de forma confiável e 2) avançar em um depurador até o ponto em que isso acontece.

Se eu não puder fazer isso, por qualquer motivo, tenho dois outros métodos que exigem uma versão diferente do código que não exiba o bug.

  1. Execute as duas versões do código lado a lado em depuradores. Dê um passo até que o mau faça algo diferente do bom.

  2. Alternativa executando as versões boas e ruins do código. Tenha um diff ou alguma outra lista das diferenças entre as versões. Em seguida, altere incrementalmente o código de uma das versões para torná-la mais próxima da outra. Se o ruim se tornar bom, ou o bom se tornar ruim, eu recuo e faço uma mudança menor. Dessa maneira, eu entendo o bug. Penso nisso como "enfrentar os dois lados do problema e trabalhar em direção ao centro". Este método não requer um depurador.

Se o problema é difícil de reproduzir, então eu preciso tanta informação como eu posso conseguir, como um despejo de pilha, quando se faz acontecer. Portanto, garanto que posso obter esses diagnósticos, aguardar a ocorrência do problema e espero ter informações suficientes para encontrá-lo.


1

Se você foi designado para fazer o trabalho em mãos como programador júnior, há pelo menos uma pessoa que acreditava que você era capaz de lidar com tudo sozinho.

Então, antes de pedir ajuda aos seus superiores, escreva em um pedaço de papel a lista de etapas / métodos que você seguiu para rastrear o bug, até que ponto você o seguiu, por que desistiu de cada método e o que aprendeu em cada tentativa. Resuma também o que aprendeu sobre o projeto até agora.

As chances são de que, quando você terminar de escrever isso, o que pode ser feito se torne cegamente óbvio. Caso isso aconteça, basta seguir o que se revelou para reproduzir o erro e tentar consertar. Caso contrário, você tem uma base sobre a qual pode conversar com seus superiores. Se você pedir a ajuda deles sem mostrar o que fez, eles podem causar uma impressão negativa em você.

Mas, se você esclarecer a situação e voltar depois do fim de semana, poderá resolvê-lo rapidamente, sem a ajuda de ninguém. Isso acontece o tempo todo.


"Se você foi designado para fazer o trabalho em mãos como programador júnior, há pelo menos uma pessoa que acreditava que você era capaz de lidar com tudo sozinho." Onde eu estava trabalhando, espera-se que todos os desenvolvedores solicitem ajuda se, depois de fazer sua homeowrk, eles não tiverem uma solução, isso se chama trabalho em equipe.
mattnz

@mattnz Tudo o que sugiro é que, antes de pedir ajuda, faça uma documentação dos esforços realizados até o momento e verifique se todas as opções conhecidas estão esgotadas. Não sei como chamar isso, mas nunca questionei o que você chama de trabalho em equipe.
vpit3833

Eu queria destacar o '... capaz de lidar com tudo sozinho', implicava para mim que você estava por conta própria. Fico feliz em saber que o interpretei um pouco mais forte do que você pretendia.
mattnz

0

Precisamos saber o quão difícil é reproduzir, pois o método é bem diferente. Para um defeito reproduzido de forma confiável, automatize a causa do defeito. Use depuradores e rastreios de depuração (os rastreios têm menos impacto nos defeitos do tipo de condição de corrida). Seja metódico. Um passo de cada vez, cada passo fornece mais informações, mesmo confirmando o que você já sabe. Se você obtiver um resultado surpresa, pare, entenda-o 100% antes de prosseguir. É dolorosamente lento, mas sempre leva você ao resultado final, se você der tempo suficiente.

Se você não pode repô-lo, então você tem um problema, como confirma que o corrigiu. Coloque o código de depuração e deixe lá. Eventualmente, pergunte a si mesmo, "Fechado: DNR" é uma opção válida? (Fez / Não pôde repordenar). Nos negócios, eventualmente, é uma decisão de custo / benefício.

Não assuma que suas bibliotecas estão corretas, confirme que estão.

Faça uma pausa, seja pragmático sobre o custo versus a necessidade de corrigir e, acima de tudo, peça a alguém que se sente ao seu lado e ajude.


0

Muitas boas respostas aqui. Algumas outras dicas:

As UIs raramente vivem isoladas. Crie um programa de teste com o conjunto mínimo de recursos necessários para reproduzir o bug. Se a interface do usuário for bem projetada, você poderá dissociar os componentes da interface com falha e executá-los isoladamente em um programa de teste. Você ainda pode reproduzir o problema? Nesse caso, é provável que o problema esteja na sua estrutura ou estrutura da interface do usuário. Verifique sua estrutura da interface do usuário - especialmente atente para elementos invisíveis. Tente aprender exatamente o que acontece quando você clica no ListView e ele não responde - quais manipuladores de eventos são chamados? Lembre-se de que podem existir erros na própria estrutura da interface do usuário - não chegue a essa conclusão, mas não a descarte completamente. Um teste rápido é atualizar sua versão do Mosync e verificar se os sintomas estão em conformidade.

Na sua falta: O que resta no seu programa de teste? Entenda todos os componentes do que resta, principalmente os threads em execução. Algo fazendo manutenção de banco de dados em segundo plano? Um spooler de arquivo de algum tipo? Código de monitoramento de comportamento do usuário da NSA? A interface do usuário está trabalhando com alguns desses componentes (possivelmente nos bastidores)? De quais operações de segundo plano a interface do usuário depende?

Enquanto você estiver lendo o código - o que você deveria dedicar bastante tempo, dada a dificuldade do bug - observe algumas práticas ruins que podem estar ocultando o bug. Especificamente, você vê isso?

try {
    SaveTheWorld();
} catch (std::exception& ex) { /* oh it didn't work, let's just ignore it */ }

Essa é uma prática incrivelmente ruim e, como tal, é bastante comum (ei, olha, não caiu!). Certifique-se de atualizar qualquer código que esteja fazendo isso para pelo menos registrá-lo - de preferência remova completamente o tratamento de exceções falsas. (Uma regra prática é que, se você não sabe qual é a exceção, não está preparado para lidar com isso.) Se estiver interagindo com APIs de estilo C, observe os valores de retorno do código de erro descartados e verifique se você está verificando informações de status de erro de qualquer ferramenta com a qual esteja interagindo.

Vendo como o seu programa de teste agora está lidando adequadamente com as falhas e você leu o log que produziu, mas ainda nada destaca o bug, procure interfaces que possam ser analisadas. Existe uma transação de rede que deveria estar acontecendo ocultamente? Nesse caso, pressione-o com o Wireshark. Transação de banco de dados? Tente algum log de consulta ou verifique o status do servidor de banco de dados. Compartilhamento de sistema de arquivos ou rede sendo atingido? Verifique os arquivos intermediários ou use um depurador para rastrear E / S. E / S de hardware? Monitorar e sondar. Seja empírico. A interface do usuário pode estar pendurada em alguma operação em segundo plano que você não antecipou.

Por fim: não entre em pânico. Mantenha a calma e acompanhe o que você tentou. Se você ainda não conseguir encontrá-lo, terá que se tornar um "problema conhecido" para ser rastreado em um dia chuvoso. Você precisará de muito material para justificar essa decisão, se for necessário.


0

No esquema das coisas, os bugs reproduzíveis são (relativamente) fáceis! Por quê? Porque você sempre pode hackear o código ao mínimo necessário até que o bug desapareça e depois trabalhar novamente para descobrir qual código o causa. Então esse é um método. É reproduzível, você tem o bicho ali sob seu controle. Você pode cutucar e experimentar. Você pode até dissecá-lo, se quiser.

Seu primeiro objetivo é entender por que o bug está acontecendo no seu código. Não tente consertar inicialmente. Apenas tente entender . Se você tentar consertá-lo sem entendê-lo, estará invadindo e provavelmente introduzirá dívida técnica , mesmo que você o resolva.

Percorra o comportamento do aplicativo, linha por linha. Observe os valores das variáveis. Observe o fluxo de controle. Onde o comportamento se desvia primeiro do que seu entendimento diz que deveria ser? Você entende como o sistema operacional envia eventos para o seu aplicativo? Se você é prejudicado pelo problema da "caixa preta", você pode obter a fonte para bibliotecas / estruturas compiladas, permitindo avançar em um nível mais profundo, se for necessário?

Você tem um commit no seu sistema de controle de versão que não produz esse bug? (Você está usando o controle de versão, não é?) Se você possui esse commit, pode fazer uma pesquisa binária no histórico para descobrir exatamente onde o bug foi introduzido.

Seus objetivos devem ser: (1) entender - determinar a causa e para esse fim, tentar (2) examinar, entender o comportamento do aplicativo em detalhes (3) isolar o problema, fazendo com que ele desapareça e, em seguida, examinando e compreendendo o delta que permitiu que você fizesse isso

Mas definitivamente não fique lá por semanas se estiver realmente preso. Você também precisa contar a alguém da sua organização. Solicite ajuda onde puder e após um certo ponto, certamente cabe a você dizer à gerência que sente que encontrou uma barreira ao progresso. Mas você provavelmente será capaz de resolver isso se acertar em vários ângulos diferentes, todos focados no aprendizado e no entendimento.

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.