Quer saber onde ocorreu o GPF ?

Quer saber onde ocorreu o GPF ?

Postby Rossine » Wed Oct 08, 2008 1:06 pm

Olá,

Deixo aqui um programa que fiz para mostrar como é possível ver onde ocorreu o erro de GPF. É necessário colocar a chamada a função "SetUnhandledExceptionFilter()" dentro da "function MAIN".

Code: Select all  Expand view  RUN

#include "fivewin.ch"

function Main()

SetUnhandledExceptionFilter( @GpfHandler() )

msgstop( "-Simulando erro GPF-" )

   __GenGpf()

msgstop( "Não vou chegar aqui !!!" )

return NIL

#include "hbexcept.ch"

*******************
Function GpfHandler( Exception )
*******************

   local cMsg, nCode, oError

**   TraceLog( "GPF:", Exception )

**   memowrit( "gpf.txt", valtoprg( Exception ) )

   IF Exception <> NIL
      nCode := Exception:ExceptionRecord:ExceptionCode
      SWITCH nCode
         CASE EXCEPTION_ACCESS_VIOLATION
              cMsg := "EXCEPTION_ACCESS_VIOLATION - O thread tentou ler/escrever num endereço virtual ao qual não tinha acesso."
              EXIT

         CASE EXCEPTION_DATATYPE_MISALIGNMENT
              cMsg := "EXCEPTION_DATATYPE_MISALIGNMENT - O thread tentou ler/escrever dados desalinhados em hardware que não oferece alinhamento. Por exemplo, valores de 16 bits precisam ser alinhados em limites de 2 bytes; valores de 32 bits em limites de 4 bytes, etc. "
              EXIT

         CASE EXCEPTION_ARRAY_BOUNDS_EXCEEDED

              cMsg := "EXCEPTION_ARRAY_BOUNDS_EXCEEDED - O thread tentou acessar um elemento de array fora dos limites e o hardware possibilita a checagem de limites."
              EXIT

         CASE EXCEPTION_FLT_DENORMAL_OPERAND
              cMsg := "EXCEPTION_FLT_DENORMAL_OPERAND - Um dos operandos numa operação de ponto flutuante está desnormatizado. Um valor desnormatizado é um que seja pequeno demais para poder ser representado no formato de ponto flutuante padrão."
              EXIT

         CASE EXCEPTION_FLT_DIVIDE_BY_ZERO
              cMsg := "EXCEPTION_FLT_DIVIDE_BY_ZERO - O thread tentou dividir um valor em ponto flutuante por um divisor em ponto flutuante igual a zero."
              EXIT

         CASE EXCEPTION_FLT_INEXACT_RESULT
              cMsg := "EXCEPTION_FLT_INEXACT_RESULT - O resultado de uma operação de ponto flutuante não pode ser representado como uma fração decimal exata."
              EXIT

         CASE EXCEPTION_FLT_INVALID_OPERATION
              cMsg := "EXCEPTION_FLT_INVALID_OPERATION - Qualquer operação de ponto flutuante não incluída na lista."
              EXIT

         CASE EXCEPTION_FLT_OVERFLOW
              cMsg := "EXCEPTION_FLT_OVERFLOW - O expoente de uma operação de ponto flutuante é maior que a magnitude permitida pelo tipo correspondente."
              EXIT

         CASE EXCEPTION_FLT_STACK_CHECK
              cMsg := 'EXCEPTION_FLT_STACK_CHECK - A pilha ficou desalinhada ("estourou" ou "ficou abaixo") como resultado de uma operação de ponto flutuante.'
              EXIT

         CASE EXCEPTION_FLT_UNDERFLOW
              cMsg := "EXCEPTION_FLT_UNDERFLOW - O expoente de uma operação de ponto flutuante é menor que a magnitude permitida pelo tipo correspondente."
              EXIT

         CASE EXCEPTION_INT_DIVIDE_BY_ZERO
              cMsg := "EXCEPTION_INT_DIVIDE_BY_ZERO - O thread tentou dividir um valor inteiro por um divisor inteiro igual a zero."
              EXIT

         CASE EXCEPTION_INT_OVERFLOW
              cMsg := "EXCEPTION_INT_OVERFLOW - O resultado de uma operação com inteiros causou uma transposição (carry) além do bit mais significativo do resultado."
              EXIT

         CASE EXCEPTION_PRIV_INSTRUCTION
              cMsg := "EXCEPTION_PRIV_INSTRUCTION - O thread tentou executar uma instrução cuja operação não é permitida no modo de máquina atual."
              EXIT

         CASE EXCEPTION_IN_PAGE_ERROR
              cMsg := "EXCEPTION_IN_PAGE_ERROR - O thread tentou acessar uma página que não estava presente e o sistema não foi capaz de carregar a página. Esta exceção pode ocorrer, por exemplo, se uma conexão de rede é perdida durante a execução do programa via rede."
              EXIT

         CASE EXCEPTION_ILLEGAL_INSTRUCTION
              cMsg := "EXCEPTION_ILLEGAL_INSTRUCTION - O thread tentou executar uma instrução inválida."
              EXIT

         CASE EXCEPTION_NONCONTINUABLE_EXCEPTION
              cMsg := "EXCEPTION_NONCONTINUABLE_EXCEPTION - O thread tentou continuar a execução após a ocorrência de uma exceção irrecuperável."
              EXIT

         CASE EXCEPTION_STACK_OVERFLOW
              cMsg := "EXCEPTION_STACK_OVERFLOW - O thread esgotou sua pilha (estouro de pilha)."
              EXIT

         CASE EXCEPTION_INVALID_DISPOSITION
              cMsg := "EXCEPTION_INVALID_DISPOSITION - Um manipulador (handle) de exceções retornou uma disposição inválida para o tratador de exceções. Uma exceção deste tipo nunca deveria ser encontrada em linguagens de médio/alto nível."
              EXIT

         CASE EXCEPTION_GUARD_PAGE
              cMsg := "CASE EXCEPTION_GUARD_PAGE"
              EXIT

         CASE EXCEPTION_INVALID_HANDLE
              cMsg := "EXCEPTION_INVALID_HANDLE"
              EXIT

         CASE EXCEPTION_SINGLE_STEP
              cMsg := "EXCEPTION_SINGLE_STEP Um interceptador de passos ou outro mecanismo de instrução isolada sinalizou que uma instrução foi executada."
              EXIT

         CASE EXCEPTION_BREAKPOINT
              cMsg := "EXCEPTION_BREAKPOINT - Foi encontrado um ponto de parada (breakpoint)."
              EXIT

         DEFAULT
            cMsg := "UNKNOWN EXCEPTION (" + cStr( Exception:ExceptionRecord:ExceptionCode ) + ")"
      END

**      IF cMsg <> NIL
**         Tracelog( "GPF Intercepted!", cMsg )
**         Alert( "GPF Intercepted!" + CRLF + cMsg )
**      ENDIF
   ENDIF

**   Throw( ErrorNew( "GPFHANDLER", 0, 0, ProcName(), "Erro de GPF", { cMsg, Exception, nCode }, Procfile(), Procname(), procline() ) )

   oError := ErrorNew( "GPFHANDLER", 0, 0, ProcName(), "Erro de GPF", { cMsg, Exception, nCode }, Procfile(), Procname(), procline() )

   ErrorDialog( oError )
   
RETURN EXCEPTION_EXECUTE_HANDLER



É preciso mudar isto em ERRSYSW.PRG

Code: Select all  Expand view  RUN

/*************
*   ErrorDialog()
*/
*static function ErrorDialog( e ) // -> logical or quits App.
function ErrorDialog( e ) // -> logical or quits App.



OBS: Compile este exemplo com o ERRSYSW.PRG com a mudança acima.

Com isto quando ocorrer o erro de GPF, será mostrada a lista de erros do FWH.

Espero que sirva para vocês :lol:

Abraços,

Rossine.
Obrigado, Regards, Saludos

Rossine.

Harbour and Harbour++
Rossine
 
Posts: 344
Joined: Tue Oct 11, 2005 11:33 am

Postby Rossine » Wed Oct 08, 2008 7:19 pm

Olá Antonio,

Seria conveniente incluir isto em ERRSYSW.PRG de FWH ?

Code: Select all  Expand view  RUN
************************
init procedure TRATA_GPF
************************

SetUnhandledExceptionFilter( @GpfHandler() )

return NIL

#include "hbexcept.ch"

**************************
static function GpfHandler( Exception )
**************************

   local cMsg, nCode, oError

**   TraceLog( "GPF:", Exception )

**   memowrit( "gpf.txt", valtoprg( Exception ) )

   IF Exception <> NIL
      nCode := Exception:ExceptionRecord:ExceptionCode
      SWITCH nCode
         CASE EXCEPTION_ACCESS_VIOLATION
              cMsg := "EXCEPTION_ACCESS_VIOLATION - O thread tentou ler/escrever num endereço virtual ao qual não tinha acesso."
              EXIT

         CASE EXCEPTION_DATATYPE_MISALIGNMENT
              cMsg := "EXCEPTION_DATATYPE_MISALIGNMENT - O thread tentou ler/escrever dados desalinhados em hardware que não oferece alinhamento. Por exemplo, valores de 16 bits precisam ser alinhados em limites de 2 bytes; valores de 32 bits em limites de 4 bytes, etc. "
              EXIT

         CASE EXCEPTION_ARRAY_BOUNDS_EXCEEDED

              cMsg := "EXCEPTION_ARRAY_BOUNDS_EXCEEDED - O thread tentou acessar um elemento de array fora dos limites e o hardware possibilita a checagem de limites."
              EXIT

         CASE EXCEPTION_FLT_DENORMAL_OPERAND
              cMsg := "EXCEPTION_FLT_DENORMAL_OPERAND - Um dos operandos numa operação de ponto flutuante está desnormatizado. Um valor desnormatizado é um que seja pequeno demais para poder ser representado no formato de ponto flutuante padrão."
              EXIT

         CASE EXCEPTION_FLT_DIVIDE_BY_ZERO
              cMsg := "EXCEPTION_FLT_DIVIDE_BY_ZERO - O thread tentou dividir um valor em ponto flutuante por um divisor em ponto flutuante igual a zero."
              EXIT

         CASE EXCEPTION_FLT_INEXACT_RESULT
              cMsg := "EXCEPTION_FLT_INEXACT_RESULT - O resultado de uma operação de ponto flutuante não pode ser representado como uma fração decimal exata."
              EXIT

         CASE EXCEPTION_FLT_INVALID_OPERATION
              cMsg := "EXCEPTION_FLT_INVALID_OPERATION - Qualquer operação de ponto flutuante não incluída na lista."
              EXIT

         CASE EXCEPTION_FLT_OVERFLOW
              cMsg := "EXCEPTION_FLT_OVERFLOW - O expoente de uma operação de ponto flutuante é maior que a magnitude permitida pelo tipo correspondente."
              EXIT

         CASE EXCEPTION_FLT_STACK_CHECK
              cMsg := 'EXCEPTION_FLT_STACK_CHECK - A pilha ficou desalinhada ("estourou" ou "ficou abaixo") como resultado de uma operação de ponto flutuante.'
              EXIT

         CASE EXCEPTION_FLT_UNDERFLOW
              cMsg := "EXCEPTION_FLT_UNDERFLOW - O expoente de uma operação de ponto flutuante é menor que a magnitude permitida pelo tipo correspondente."
              EXIT

         CASE EXCEPTION_INT_DIVIDE_BY_ZERO
              cMsg := "EXCEPTION_INT_DIVIDE_BY_ZERO - O thread tentou dividir um valor inteiro por um divisor inteiro igual a zero."
              EXIT

         CASE EXCEPTION_INT_OVERFLOW
              cMsg := "EXCEPTION_INT_OVERFLOW - O resultado de uma operação com inteiros causou uma transposição (carry) além do bit mais significativo do resultado."
              EXIT

         CASE EXCEPTION_PRIV_INSTRUCTION
              cMsg := "EXCEPTION_PRIV_INSTRUCTION - O thread tentou executar uma instrução cuja operação não é permitida no modo de máquina atual."
              EXIT

         CASE EXCEPTION_IN_PAGE_ERROR
              cMsg := "EXCEPTION_IN_PAGE_ERROR - O thread tentou acessar uma página que não estava presente e o sistema não foi capaz de carregar a página. Esta exceção pode ocorrer, por exemplo, se uma conexão de rede é perdida durante a execução do programa via rede."
              EXIT

         CASE EXCEPTION_ILLEGAL_INSTRUCTION
              cMsg := "EXCEPTION_ILLEGAL_INSTRUCTION - O thread tentou executar uma instrução inválida."
              EXIT

         CASE EXCEPTION_NONCONTINUABLE_EXCEPTION
              cMsg := "EXCEPTION_NONCONTINUABLE_EXCEPTION - O thread tentou continuar a execução após a ocorrência de uma exceção irrecuperável."
              EXIT

         CASE EXCEPTION_STACK_OVERFLOW
              cMsg := "EXCEPTION_STACK_OVERFLOW - O thread esgotou sua pilha (estouro de pilha)."
              EXIT

         CASE EXCEPTION_INVALID_DISPOSITION
              cMsg := "EXCEPTION_INVALID_DISPOSITION - Um manipulador (handle) de exceções retornou uma disposição inválida para o tratador de exceções. Uma exceção deste tipo nunca deveria ser encontrada em linguagens de médio/alto nível."
              EXIT

         CASE EXCEPTION_GUARD_PAGE
              cMsg := "CASE EXCEPTION_GUARD_PAGE"
              EXIT

         CASE EXCEPTION_INVALID_HANDLE
              cMsg := "EXCEPTION_INVALID_HANDLE"
              EXIT

         CASE EXCEPTION_SINGLE_STEP
              cMsg := "EXCEPTION_SINGLE_STEP Um interceptador de passos ou outro mecanismo de instrução isolada sinalizou que uma instrução foi executada."
              EXIT

         CASE EXCEPTION_BREAKPOINT
              cMsg := "EXCEPTION_BREAKPOINT - Foi encontrado um ponto de parada (breakpoint)."
              EXIT

         DEFAULT
            cMsg := "UNKNOWN EXCEPTION (" + cStr( Exception:ExceptionRecord:ExceptionCode ) + ")"
      END

**      IF cMsg <> NIL
**         Tracelog( "GPF Intercepted!", cMsg )
**         Alert( "GPF Intercepted!" + CRLF + cMsg )
**      ENDIF
   ENDIF

**   Throw( ErrorNew( "GPFHANDLER", 0, 0, ProcName(), "Erro de GPF", { cMsg, Exception, nCode }, Procfile(), Procname(), procline() ) )

   oError := ErrorNew( "GPFHANDLER", 0, 0, ProcName(), "Erro de GPF", { cMsg, Exception, nCode }, Procfile(), Procname(), procline() )

   ErrorDialog( oError )
   
RETURN EXCEPTION_EXECUTE_HANDLER



Obrigado,

Rossine.
Obrigado, Regards, Saludos

Rossine.

Harbour and Harbour++
Rossine
 
Posts: 344
Joined: Tue Oct 11, 2005 11:33 am

Postby Antonio Linares » Thu Oct 09, 2008 12:58 pm

Rossine,

Cuando se produce un GPF se debe intentar no usar más la máquina virtual de Harbour/xHarbour pues lo que puede ocurrir es que generemos un error sobre otro error.

El actual gestor de excepciones (GPFs) de Harbour/xHarbour proporciona información sobre la pila de llamadas, que es lo que más nos puede ayudar para localizar el GPF.
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Antonio Linares
Site Admin
 
Posts: 42161
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain


Return to FiveWin para Harbour/xHarbour

Who is online

Users browsing this forum: Google [Bot] and 54 guests