Pergunta

Eu tenho um algum lugar bug que está causando meu aplicativo para simplesmente desaparecer sem uma mensagem de erro ou algo parecido. O aplicativo apenas desaparece da tela e ele não é mais listado no Gerenciador de tarefas.

O aplicativo é um aplicativo C ++ Builder (CBuilder2007), e eu tentei tudo o que tenho pensar para tentar pegar esse erro. Isso acontece muito raramente, ele nunca deixou de funcionar na minha máquina e apenas uma vez nas máquinas de teste que temos no escritório. Com um de nossos clientes acontece um pouco mais frequentes, mas ainda não encontrar uma maneira de fazer isso acontecer, ou para encontrar as circunstâncias em que isso acontece. É um aplicativo de vários segmentos pesado.

Eu tenho MadExcept habilitado neste app, mas ele não pegar nada. Já manipuladores usando as rotinas set_terminate e RTL set_unexpected acrescentou, sem qualquer sorte.

A única informação que tenho é de um "app loader" wrapper eu fiz, para obter o código de retorno do aplicativo principal. Ele sai com o código C0000005, que eu acredito meios uma violação de acesso aconteceram. O estranho é que, como mencionado, não há nem mesmo caixa de erro do Windows ou algo parecido.

A pergunta seria: quaisquer ideias para tentar pegar isso? Como eu não tem sequer uma pista onde isso pode estar acontecendo (Eu tenho um monte de registrar em todo o aplicativo, mas o "trail" antes de o aplicativo trava não levar a qualquer lugar) minha idéia com as rotinas set_terminate e set_unexpected foi para obter um rastreamento de pilha para tentar ver onde o erro foi gerado, mas até agora essas rotinas não estão sendo chamados em tudo (pelo menos a única vez que isso aconteceu aqui no meu escritório)

Agradecemos antecipadamente


[Update 22.Sept.2009] Usando AddVectoredHandlerException eu era capaz de conseguir uma pilha de chamadas a partir do acidente, e agora posso começar a tentar isolar e corrigir o erro. Thanks !!!

Foi útil?

Solução

terminate / unexpected é chamado apenas pelo tempo de execução C ++, e somente para exceções C ++.

Violação de acesso é uma exceção SEH - para pegar isso, você precisa SetUnhandledExceptionFilter , ou AddVectoredExceptionHandler (se for> = XP). Você poderia, então, criar um minidump, usando MiniDumpWriteDump e relacionados.

Outras dicas

Eu me deparei com problemas como este algumas vezes, onde a aplicação parece simplesmente parar. Não manipuladores de exceção ou manipuladores de acidente ou como são chamados. O aplicativo simplesmente parece terminar imediatamente.

Infelizmente, não posso oferecer qualquer conselho fácil sobre como descobrir isso. As outras respostas aqui têm algumas boas ideias. Se você ainda não ter algo para pegar exceções não tratadas conforme reponse do PiotrLegnica, então você deve fazê-lo.

No entanto, se o programa é realmente terminando instantaneamente como as vezes que eu vi isso, então mesmo um manipulador registrado com SetUnhandledExceptionFilter não vai ajudar. O programa é parar toda a execução e abandono de memória antes de o manipulador é sempre invocado.

Algumas idéias para que vêm à mente que:

  • Verifique se o seu código base para qualquer uso do TerminateProcess ou TerminateThread . Eu posso estar errado, mas eu acredito que o uso destes pode ser capaz de causar os sintomas que você está vendo.
  • Verifique qualquer uso de ponteiros de função, incluindo chamadas de retorno e WindowProcs passados ??para APIs do Windows. Certifique-se de que as convenções de chamada, listas de parâmetros e valores de retorno durante todo o jogo corretamente. Se um ponteiro de função está sendo escalado para fazer a compilação de código, ele pode estar escondendo uma incompatibilidade que poderia estar causando as coisas ruins aconteçam.
  • Considerar quaisquer bibliotecas ou componentes (ActiveX ou tais) que você está usando 3-parte. Talvez eles tenham um bug no seu próprio código causando esse problema em situações obscuras. Você poderia tentar colocar declarações de registro antes e após as chamadas para as suas funções para ver se isso pode fixar para baixo, onde o programa pára.
  • E se nada mais ajuda, colocar mais registro de todo o seu próprio código.

E sobre o tema da exploração madeireira: Quando eu tinha para ajudar a rastrear um problema como este, onde no meu trabalho, acabamos fazendo um mecanismo de registro que criaria um registro chamado exclusivamente cada vez que o programa começou e seria excluí-lo se o programa terminou normalmente. Dessa forma, um outro arquivo de log seria deixado na existência cada vez que o problema rescisão ocorreu. Usamos um carimbo de data e hora como parte do aspecto único de nomeação. O conteúdo dos registros era simplesmente um registro de quais ações estavam acontecendo no programa. Passamos por várias iterações de examinar os registros e, em seguida, adicionar mais declarações de registro até que este finalmente nos levou a fonte. E enquanto rastrear o problema, este mecanismo nos deu uma idéia muito clara sobre o quão frequentemente o problema estava ocorrendo. Você pode considerar algo semelhante.

Eu já vi isso acontecer com código C ++ duas vezes antes:

  1. Ao carregar dinamicamente uma API do Windows usando LoadLibrary e GetProcAddress e, em seguida, chamando-o através de um ponteiro de função declarado com a convenção de chamada errada (ele deve ter tido __stdcall mas não o fez).

  2. Quando uma classe tinha um ponteiro de função como uma variável de membro, e o ponteiro de função foi chamado antes de ter sido iniciado.

Você tem que executar o aplicativo no modo de depuração, e fazer um teste de esforço, executando conjunto de cenário complicado mais e mais, para que você possa capturar a exceção no modo de depuração.

Além disso, tente rever novamente o código que contém acessando a memória compartilhada entre seus segmentos, pode ser o problema de mulithreading, você pode tentar colocar fechaduras em cada acesso de memória compartilhada para a obtenção de certeza mulithreading é a razão (mas isso vai diminuir o desempenho )

Re: o desaparecimento aplicativo, que as máquinas dos clientes têm o "Relatório de erros" Definição desativado no Windows? Está enterrado no painel de controle "System", e quando ele desligou o diálogo de notificação acidente normal do Windows é suprimida.

Talvez a adição de um bom, velho manipulador de sinal moda poderia pelo menos dar alguma indicação do que aconteceu?

Você tem uma situação difícil se você não pode reproduzi-lo localmente. Capturar um despejo de memória, ou pegar o programa no ato com um depurador é certamente a melhor opção, como já foi sugerido.

Se este fosse o meu problema, eu tentaria monitoramento com Process Monitor da Sysinternals. Configurá-lo para assistir apenas o seu processo e ter certeza que é apoiado por um arquivo se ele vai levar um longo tempo. Isso pode lhe dizer qual thread está ativo e que está acontecendo quando o processo termina. Você também pode tentar encontrar o equivalente do 'fardo' para Windows -. Um programa para chamadas de sistema do monitor

Há mais duas coisas que eu vi fazer isso no passado, que você pode considerar: estouro de pilha (recursão infinita, maus parâmetros causando grandes variáveis ??temporárias para ser localizado na pilha etc), ou uma exceção não tratada em um secundário fio.

Configurar seu aplicativo para escrever um minidump no caso de um acidente.

Eu não sei como isso está em CBuilder, mas no visual studio que você pode carregar este despeja diretamente e mostra-lhe uma pilha de chamadas completa e a linha de código fonte que causou o acidente.

Eu usei isso muito para encontrar a causa de acidentes que aconteceram nas máquinas dos clientes.
No entanto, especialmente para aplicações multi-threaded é provável que o erro real (por exemplo, a memória foi liberado para início) aconteceu um pouco antes do acidente real, por isso ainda pode ser muito difícil encontrar a causa raiz.

Inscrever-se para o Relatório de Erros do Windows. As chances são de que alguns de seus clientes irá relatar o AV para a Microsoft, que felizmente vou compartilhar os rastreamentos de pilha recolhidos com você. Como benefício, você tem números concretos sobre a confiabilidade de sua aplicação. Gestão ama aqueles. Por exemplo. você pode definir uma meta de "reduzir a frequência de erros em 50% até 2010".

Coloque o seu aplicativo em execução, em seguida, anexar o windbg (crash-mode) que a primeira ocorrência de exceção de segunda oportunidade é gerado despejo. Lembre-se de colocar os arquivos de símbolo (PDB).

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top