18 de fev. de 2007

Como determinar onde gerou uma exceção?

Uma das coisas mais desagradáveis é testar um programa, instalar ele no cliente e ele cair com uma exceção no meio da demonstração. Na máquina de desenvolvimento, a IDE gentilmente mostra onde a exceção foi gerada. Mas no cliente, não.

Na JCL (Jedi Code Library) existe uma unit chamada JclDebug que deve ser usada em conjunto com o mecanismo do JCL para tratamento de exceções não tratadas. Esse mecanismo consiste basicamente em determinar onde a exceção foi gerada (em qual linha, função/procedure e unit) bem como gerar um dump da pilha do programa, o que permite ter uma idéia da sequência de processamento que resultou na exceção.

A documentação da JCL não é muito clara sobre como usar esse mecanismo. O problema maior é saber como preparar o executável para poder usar o mecanismo. Esta é a "receita do bolo":

  1. Na instalação do JCL, marque a opção IDE experts|Debug extension e marque a opção Sample exception dialogs.
  2. De volta a IDE, abra seu projeto
  3. File|New|Other...|Dialogs
  4. Dê um clique duplo no ícone do Exception Dialog
  5. Salve seu projeto dando um File|Save all
  6. Marque a opção Project|Insert JCL Debug Data
  7. Dê um Project|Build (um dialog box adicional do JCL irá aparecer se o build for bem sucedido)
Se você optar por não utilizar a janela de exceção do JCL, não precisa fazer os passos 3-4-5. Entretanto, vale a pena testar pelo menos uma vez essa caixa de diálogo e dar uma olhada como o relatório de erro é criado.
  • Para isto funcionar, nunca compacte o executável (com compactadores do tipo UPX). Os compactadores de executável costumam alterar os endereços de carga dos módulos, de modo que o endereço de uma função/procedure quando o executável é gerado fica diferente do endereço quando o executável é executado. Resultado: as informações capturadas na exceção estão todas erradas!
  • Exceções que ocorrem muito cedo (na inicialização das units) ou muito tarde (na finalização das units) costumam não ser capturadas por qualquer mecanismo de captura de exceções que você imaginar; para evitar isso, vá no fonte do seu DPR e garanta que a unit que inicializa seu mecanismo de captura de exceções seja a primeita unit da lista (difícil de fazer, especialmente se você usa a unit ShareMem).
  • Se você desabilitar a opção Project/Insert JCL Debug Data, terá de gerar um mapa completo de linkagem do executável e distribuir esse arquivo (.MAP) junto com seu programa. Mas é muito mais cômodo deixar a opção habilitada.
  • Se quiser um dump da pilha extremamento detalhado, vá em Project| Options, aba Compiler e marque a opção Use debug DCUs

Links relacionados

Nenhum comentário: