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
Abraços,
Rossine.