Strukturerad undantagshantering

Strukturerad undantagshantering ( SEH  - Structured Exception Handling ) är en mekanism för att hantera program- och hårdvaruundantag i Microsoft Windows operativsystem som tillåter programmerare att kontrollera undantagshantering, och är också ett felsökningsverktyg [ 1 ] .

Undantag och undantagshantering

Ett undantag är en händelse under programkörning som gör att det beter sig onormalt eller felaktigt. Det finns två typer av undantag: hårdvara som genereras av processorn och programvara som genereras av operativsystemet och applikationsprogrammen . Den strukturerade undantagshanteringsmekanismen låter dig hantera både program- och hårdvaruundantag på samma sätt.

Implementering

Nyckelord

Mekanismen stöds endast av Microsoftkompilatornivå genom implementering av icke - standardiserade syntaxkonstruktioner __tryoch . Nyckelordet används för att markera en kodsektion där ett undantag kommer att hanteras av ett eller flera block . Koden i blocket kommer alltid att exekveras oavsett andra block och [2] . __except__finally__try__except__finally__try__except

Användningsexempel i C och C++

__prova { // skyddad kod, // som är placerad i en SEH-ram } __except ( undantagsfilter ) { _ // undantagshanterare } __slutligen { // kod som ska köras ändå }

Undantagsfilter kan vara vanliga funktioner som returnerar tre konstanta uttryck: [3]

  • EXCEPTION_EXECUTE_HANDLER - indikerar den här hanterarens förmåga att hantera undantaget. Efter att ha mottagit ett sådant värde, slutar operativsystemet att söka efter relevanta undantagshanterare och, efter att ha avvecklat stacken, överförs kontrollen till den första som returnerade EXCEPTION_EXECUTE_HANDLER

  • EXCEPTION_CONTINUE_EXECUTION - indikerar en buggfix. Systemet kommer återigen att överföra kontrollen till instruktionen som gav undantaget, eftersom det förväntas att det denna gång inte kommer att skapa ett undantag. [fyra]
  • EXCEPTION_CONTINUE_SEARCH - indikerar att en lämplig förare kan hittas högre upp i stacken. Samtidigt kan returnera detta värde indikera att felet inte har hanterats. [3]

Strukturer och mekanismer som används

Varje tråd i vilken process som helst använder ett register (16-bitars väljare ) fsför att lagra en pekare till en datastruktur för trådinformationsblock som innehåller information om den tråden. Denna struktur lagrar en pekare till den senast registrerade _EXCEPTION_REGISTRATION_RECORD- strukturen i den länkade listan , som inkluderar en pekare till undantagshanteraren och en pekare till föregående _EXCEPTION_REGISTRATION_RECORD- post . [5] När en tråd skapas lägger operativsystemet till en standardundantagshanterare som anropas av . kernel32!UnhandledExceptionFilter

Prototypen för återuppringningshanterarens funktion är som följer:

EXCEPTION_DISPOSITION __cdecl _except_handler ( struct _EXCEPTION_RECORD * ExceptionRecord , void * EstablisherFrame , struct_CONTEXT * ContextRecord , _ void * DispatcherContext );

Varje gång programmeraren använder konstruktionen __tryläggs en ny instans av strukturen _EXCEPTION_REGISTRATION_RECORD, som pekar på funktionen _except_handler3 i biblioteket msvcrt.dll , till i trådens stack . Blockkod __exceptanropas __finallyfrån _except_handler3. I slutet av blocket __trylägger kompilatorn till kod som tar bort den aktuella _EXCEPTION_REGISTRATION_RECORD-posten och återställer värdet på pekaren fs:0till den föregående posten.

När ett undantag inträffar, itererar systemet genom hela kedjan av avbrottshanterare i sekvens. Varje hanterare returnerar ett värde som anger om den kan hantera detta undantag eller inte. Pekaren till slutet av listan över tillgängliga undantagshanterare är värdet som FFFFFFFFfinns på stacken efter den sista hanteraren. Om systemet hittar den önskade hanteraren överförs kontrollen till den. Samtidigt, efter att ha hittat den relevanta hanteraren för undantaget som har uppstått, överför operativsystemet inte omedelbart kontrollen till det, utan anropar återigen sekventiellt alla hanterare längs kedjan med flaggan EH_UNWINDINGför att städa upp (ringa förstöraren ) . [4] Om inget av de undantagshanterarfilter som ställts in av programmeraren returnerade EXCEPTION_EXECUTE_HANDLER eller EXCEPTION_CONTINUE_EXECUTION, exekveras UnhandledExceptionFilter standardexcepthanterarens filter, som registreras när tråden förbereds för att köras.

Handlaranrop

När ett undantag inträffar anropar operativsystemet inte direkt undantagsfiltret (som är ansvarigt för om en viss hanterare kommer att hantera undantaget som har inträffat eller inte), utan skickar sin adress till funktionen _except_handler3, varifrån filterfunktionen anropas . Den använder följande datastruktur: [6]

struct _EXCEPTION_REGISTRATION { struct _EXCEPTION_REGISTRATION * föregående ; void ( * hanterare )( PEXCEPTION_RECORD , PEXCEPTION_REGISTRATION , PCONTEXT , PEXCEPTION_RECORD ); struct scopetable_entry * scopetable ; int trylevel ; int_ebp ; _ PEXCEPTION_POINTERS xpekare ; };

Fältet *scopetablepekar på adressen till en array av strukturer scopetable_entryoch heltalsfältet på försöksnivån pekar på ett index i denna array. Fältet _ebpinnehåller värdet för stackrampekaren som fanns innan strukturen EXCEPTION_REGISTRATION skapades. [7] Funktionen _except_handler3anropar det önskade filtret och, innan han anropar hanteraren, lindar (rensar) stacken med funktionen ntdll.dll!RtlUnwind.

Om ingen av hanterarna som installerats av programmeraren gick med på att hantera undantaget, anropas en funktion UnhandledExceptionFiltersom kontrollerar om processen körs under felsökaren och informerar den om den är tillgänglig. [7] Funktionen anropar sedan standardhanterarfiltret (som ställs in av funktionen SetUnhandledExceptionFilteroch som alltid returnerar EXCEPTION_EXECUTE_HANDLER). [7] Sedan, beroende på operativsystemets inställningar, anropas antingen felsökaren eller NtRaiseHardError-funktionen, vilket visar ett felmeddelande. [7]

Anteckningar

  1. Strukturerad undantagshantering (Windows) . Hämtad 5 maj 2010. Arkiverad från originalet 25 september 2010.
  2. Om strukturerad undantagshantering (Windows) . Hämtad 5 maj 2010. Arkiverad från originalet 28 februari 2011.
  3. 1 2 Introduktion till SEH Structured Exception Handling (död länk) . Datum för åtkomst: 26 december 2012. Arkiverad från originalet den 27 mars 2014. 
  4. 1 2 WASM.IN Win32 SEH Inside (Del 1) . Hämtad 5 april 2018. Arkiverad från originalet 5 april 2018.
  5. Att använda SEH i en Win32-miljö . Hämtad 1 maj 2010. Arkiverad från originalet 24 september 2015.
  6. WASM.IN Win32 SEH från insidan (del 2) . Hämtad 5 april 2018. Arkiverad från originalet 5 april 2018.
  7. 1 2 3 4 WASM.IN Win32 SEH från insidan (del 3) . Hämtad 5 april 2018. Arkiverad från originalet 5 april 2018.