2010-04-13 2 views
9

il mio codice è abbastanza ben coperto con la gestione delle eccezioni (try..except). Non si prevede che alcune eccezioni si verifichino e alcune eccezioni si verificano abbastanza spesso, il che è previsto e ok. Ora voglio aggiungere alcuni test automatici per questo codice. Sarebbe bene sapere quante eccezioni si sono verificate durante l'esecuzione, quindi posso vedere in seguito se il numero previsto è stato sollevato o se è accaduto qualcosa di inaspettato. Non voglio ingombrare ogni blocco di gestione delle eccezioni con il codice di debug, quindi la mia domanda è:È possibile avere un hook di eccezione globale?

C'è un modo per installare una sorta di gestore di eccezioni globale che si trova proprio prima di tutti gli altri blocchi di gestione delle eccezioni? Sto cercando un posto centrale per registrare queste eccezioni.

Grazie per eventuali suggerimenti!

(E se questo conta: è Delphi 2009)

risposta

14

È possibile effettuare le seguenti operazioni:

  • preservare il valore della variabile System.RaiseExceptObjProc, che in condizioni normali Delphi app è rivolta a SysUtils.RaiseExceptObject
  • crea il tuo proc "RaiseExceptObject" e assegnalo alla variabile RaiseExceptObjProc
  • nel tuo "RaiseExceptObject" "proc è possibile fare ciò che si desidera, quindi chiamare il valore RaiseExceptObjProc salvato

Per i dettagli, vedere sopra le dichiarazioni delle variabili e delle procedure.

+0

Woohoo! Questo è tutto :) Grazie mille per questo suggerimento! E per la cronaca: 1) Firma di 'RaiseExceptObjProc':' procedure (P: PExceptionRecord) '2) sembra che non debba chiamare il vecchio' RaiseExceptObjProc' nel mio gestore 3) Ho letto da qualche parte che questo è disponibile da Delphi 2009 (buono per me), ma non sono sicuro di questo –

+0

Ok SysUtils.pas già assegna 'RaiseExceptObjProc'. Forse questo dovrebbe essere effettivamente chiamato dal mio gestore. –

+0

hey puoi per favore fornire un esempio? :) – PresleyDias

0

JCL ha è proprio dialogo eccezione. Basta aggiungere questa finestra di dialogo al progetto, gestirà tutte le eccezioni impreviste. Informazioni dettagliate situate in questa cartella JCL: jcl \ experts \ debug. C'è anche un file di testo howto che descrive passo per passo come usarlo.

+0

L'OP sta cercando l'aggancio anche nelle eccezioni * gestite *. –

8

Penso che sia possibile utilizzare la funzione API AddVectoredExceptionHandler.

Ecco un piccolo esempio su come utilizzare:

var 
    f : TFileStream; 

    function VectoredHandler(ExceptionInfo : PEXCEPTION_POINTERS): LongInt; stdcall; 
    var 
     s : String; 
    begin 
     S := Format('Exception code %x address %p'#10#13, [ExceptionInfo^.ExceptionRecord^.ExceptionCode, 
     ExceptionInfo^.ExceptionRecord^.ExceptionAddress]); 
     f.WriteBuffer(PChar(s)^, Length(s) * sizeof(wchar)); 
     FlushFileBuffers(f.Handle); 
     OutputDebugString(PChar(Format('ExceptionCode: %x', [ExceptionInfo^.ExceptionRecord^.ExceptionCode]))); 
     result := EXCEPTION_CONTINUE_SEARCH ; 
    end; 


    initialization 
     AddVectoredExceptionHandler(0, VectoredHandler); 
+0

Questo trappola le eccezioni a livello di win32, la soluzione di Dmitry Arefiev, ma più quello che ti aspettavi. – Remko

+0

Grazie per il puntamento a queste funzioni, penso che questo potrebbe tornare utile per qualcuno che esegue puro Win32. La soluzione di Dmitry era più semplice nel mio caso. –

+0

+1 Perché ho appena avuto bisogno di questa chiamata API per supportare la versione precedente di Delphi (ad esempio Delphi 6-7), in cui RaiseExceptObjProc non è esistente. –

1

È possibile aggiungere un gestore personalizzato a madExcept che consentirebbe quindi di ottenere una traccia dello stack completo, ma anche di proseguire.

+0

Ma * come * faresti questo? – Arafangion

+0

@Arafangion Vorrei iniziare leggendo la documentazione di madExcept, che ti dirà tutto quello che devi sapere. In sostanza, si crea un gestore di eccezioni (try/except) e quindi si passa l'oggetto exception a HandleException per l'elaborazione da madExcept, che esegue la magia. – mj2008

+0

La documentazione è vaga su come gestire le eccezioni * non rilevate, anche se, in particolare, quando inizi a preoccuparti della gestione delle eccezioni SEH. – Arafangion