2013-11-01 8 views
5

ich über Structured Exception Handling lese in C. Hier ist ein Beispiel-Code, der nicht wie erwartet funktioniert:Exception Handler nicht in C genannt

Dieser Code von hier genommen wird:

http://msdn.microsoft.com/en-us/library/ha52ak6a.aspx

// C4733.cpp 
// compile with: /W1 /c 
// processor: x86 
#include "stdlib.h" 
#include "stdio.h" 
void my_handler() 
{ 
    printf("Hello from my_handler\n"); 
    exit(1); 
} 

int main() 
{ 
    _asm { 
     push my_handler 
     mov  eax, DWORD PTR fs:0 
     push eax 
     mov  DWORD PTR fs:0, esp // C4733 
    } 

    *(int*)0 = 0; 
} 

Dieser Code sollte die Nachricht "Hello from my_handler" ausgeben, wenn die Ausnahme ausgelöst wird, indem versucht wird, in eine ungültige Speicheradresse zu schreiben. Es scheint jedoch, dass der Ausnahmebehandler überhaupt nicht aufgerufen wird.

Ich kompilierte diesen Code und versuchte, es mit Olly Debugger zu debuggen. Wenn die Ausnahme auftritt, übergebe ich die Ausnahme an den anwendungsdefinierten Exception-Handler (durch Drücken von Shift + F9), aber sie wird nicht aufgerufen. Ich habe einen Haltepunkt an der Ausnahmebehandlungsroutine (erste Anweisung) festgelegt, aber diesen Codeabschnitt wird nie erreicht.

Was könnte der Grund dafür sein?

+0

Sieht aus wie es eine Compilerwarnung ist, keine Laufzeitfehlerüberprüfung. Ich habe keine Windows, kann also nicht überprüfen .. – texasbruce

+0

Haben Sie versucht, Ihren Code mit '/ ZI/MTd' Compiler-Optionen zu kompilieren? Auf diese Weise habe ich das erwartete Ergebnis. – boleto

Antwort

2

Ich war mit dem gleichen Problem konfrontiert. Der Grund dafür, dass es nicht funktioniert, ist, dass my_handler vom Compiler zur verknüpften Zeit blockiert wird. Wir müssen entweder dem Compiler mitteilen, dass my_handler sicher ist, oder die Sicherheitsprüfung vollständig deaktivieren. Es gibt also zwei Möglichkeiten, damit es funktioniert. (Versuchte sowohl MSVC 2008 und 2010)

  • die SafeSEH Tabelle Deaktivieren von Add/SafeSEH: Nein zur Verknüpfungszeit.

    cl /c C4733.cpp 
    link /safeseh:no C4733.obj 
    
  • erstellen masm Datei my_handler zum SEH Tabelle hinzuzufügen. Aber the SAFESEH example on MSN hat nicht auf meinem Laptop funktioniert. Ich fand diese Lösung auf stackoverflow, um stattdessen zu arbeiten: Custom SEH handler with /SAFESEH. Aber wir müssen eine zusätzliche MASM-Prozedur erstellen, um zur externen C-Funktion zu springen.

+0

Benötigen Sie unbedingt diese MASM-Datei? Können Sie den Assembly-Code nicht einfach mit der Inline-Assembly hinzufügen? – Calmarius

+0

@Calmarius Ich bezweifle, wenn Inlining funktioniert. Es gibt einen Parameter -safeseh, der an ml.exe übergeben wird, was von cl.exe nicht unterstützt wird. FYI, kompilierte ich die ASM mit: ml.exe -Fo my.obj -c -safeseh my.asm – jichi