2010-05-06 11 views

risposta

33

Sono l'equivalente di Win32 per i segnali Unix e consentono di rilevare le eccezioni della CPU come violazione di accesso, istruzione illegale, divisione per zero.

Con le giuste opzioni del compilatore (/ EHa per Visual C++), le eccezioni C++ utilizzano lo stesso meccanismo utilizzato per lo sbobinamento dello stack per eccezioni C++ (utente) ed eccezioni SEH (OS).

A differenza delle eccezioni C++, SEH non è stato digitato ma tutti condividono la stessa struttura dati che ha un codice di eccezione (la causa) e informazioni aggiuntive su quale codice è guasto e quali registri della CPU sono stati memorizzati al momento dell'errore. Vedere GetExceptionCode e GetExceptionInformation per ulteriori dettagli su questo.

Inoltre, SEH ha una gestione "di prima scelta", che consente di registrare o gestire in altro modo l'eccezione prima dello sdoppiamento e distrugge tutte le variabili locali.

+1

Nota che il valore predefinito è stato modificato dalla gestione delle eccezioni SEH come le eccezioni C++ perché le eccezioni SEH non sono sicure da gestire come le eccezioni C++. Le eccezioni SEH sono di solito cose come le violazioni di accesso e il tentativo di eseguire lo sbiadimento in C++ in tali condizioni non è possibile e può causare la chiusura del programma. –

+3

Non c'è niente di intrinsecamente pericoloso per svelare una violazione di accesso. Naturalmente, se la violazione dell'accesso è stata causata dalla corruzione delle strutture di dati interne (in particolare gli overflow dello stack che influiscono sulle informazioni dello stack di chiamata), è probabile che lo svolgimento non funzioni, ma molti, se non la maggioranza, delle eccezioni SEH non riflettono effettivamente lo stack corruzione. –

+0

Leggete anche http://stackoverflow.com/questions/4414027/visual-c-unmanaged-code-use-eha-or-ehsc-for-c-exceptions su un brutto effetto collaterale di SEH con ellissi ignorate - Eccezioni (es. catch (...) {}) –

20

Devono sapere che non fanno parte di Standard C++: sono un'invenzione di Microsoft e possono essere utilizzati in lingue diverse dal C++.

16

A Crash Course on the Depths of Win32™ Structured Exception Handling

Tale articolo è il riferimento su come ottenere fino a velocità con SEH. 13 anni dopo, è ancora il migliore che ci sia.

C'è un argomento dedicato su MSDN per SEH vs. C++ Exception Handling Differences.

Alcune cose uno sviluppatore C++ dovrebbe conoscere se SEH è in discussione:

Scrittura C/C++ SEH Exception Handlers:

__try 
{ 
    // guarded code 
} 
__except (expression) 
{ 
    // exception handler code 
} 

Questo è la gestione delle eccezioni non C++, è il MS estensioni specifiche per agganciare dritto inot SEH. Funziona in modo molto diverso dalle eccezioni C++ run-of-the-mill. Hai bisogno di una buona comprensione di SEH per usarli.

Scrittura C/C++ SEH Termination Handlers:

__try { 
    // guarded code 
} 
__finally (expression) { 
    // termination code 
} 

Lo stesso con il gestore SEH, non confondere questo con C++ la semantica di eccezione. Hai bisogno di una buona comprensione di SEH.

_set_se_trasnlator: questa è la funzione che converte le eccezioni SEH in eccezioni di tipo C++ quando vengono utilizzate le eccezioni asincrone /EHa.

Infine, un'opinione personale: uno sviluppatore C++ dovrebbe conoscere SEH? Dopo il tuo primo debuttante, .ecxr, capirai che quando la spinta arriva a spingere le eccezioni C++ sono solo un'illusione fornita per tua comodità. L'unica cosa che sta succedendo è SEH.

+7

'__finally' non ha' (espressione) ' – Abyx

24

Recentemente ho avuto un problema che è stato causato indirettamente da SEH, in particolare a causa di una caratteristica di SEH che penso che ogni sviluppatore dovrebbe essere a conoscenza di:

Quando SEH è usato distruttori non vengono chiamati, quindi se avete codice di pulizia nel distruttore non verrà ripulito.

Il nostro problema è stato causato da una sezione critica che è stata avvolta da un oggetto con Lock nel costruttore e Unlock nel distruttore.

Avevamo una situazione di stallo e non riuscivamo a capire perché, e dopo circa una settimana di ricerca del codice e dei dump e debug abbiamo finalmente capito che c'era un'eccezione gestita da COM e che causava il problema sezione per rimanere bloccato. Abbiamo modificato un flag di compilazione in VS nelle proprietà del progetto che gli dicevano di eseguire i distruttori anche per SEH e questo risolveva il problema.

Quindi, anche se non è possibile utilizzare SEH nel codice, è possibile che si stia utilizzando una libreria che funziona (come COM) e che può causare un comportamento imprevisto.