2013-11-01 11 views
5

sto leggendo sulla gestione delle eccezioni strutturata in C. Ecco un esempio di codice che non funziona come previsto:gestore delle eccezioni non chiamata in C

Questo codice è preso da qui:

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; 
} 

Questo codice deve stampare il messaggio "Hello from my_handler" quando l'eccezione viene attivata tentando di scrivere su un indirizzo di memoria non valido. Tuttavia, sembra che il gestore delle eccezioni non venga chiamato affatto.

Ho compilato questo codice e ho provato a debuggarlo con Olly Debugger. Quando si verifica l'eccezione, provo a passare l'eccezione al gestore delle eccezioni definito dall'applicazione (premendo, MAIUSC + F9) ma non viene richiamato. Ho impostato un breakpoint sul gestore delle eccezioni (prima istruzione), ma non raggiunge mai quella sezione di codice.

Quale potrebbe essere la ragione di questo?

+0

Sembra che sia un avviso del compilatore, non un controllo degli errori di runtime. Non ho finestre quindi non posso controllare .. – texasbruce

+0

Hai provato a compilare il tuo codice con le opzioni del compilatore '/ ZI/MTd'? In questo modo, ho ottenuto il risultato previsto. – boleto

risposta

2

Mi trovavo di fronte allo stesso problema. La ragione per cui non funziona è che my_handler è bloccato dal compilatore al momento del collegamento. Abbiamo bisogno di dire al compilatore che my_handler è sicuro, o disabilitare totalmente il controllo di sicurezza. Quindi, ci sono due modi per farlo funzionare. (Provato su entrambe MSVC 2008 e 2010)

  • disattivare il tavolo SafeSEH da Add/SafeSEH: no in fase di collegamento.

    cl /c C4733.cpp 
    link /safeseh:no C4733.obj 
    
  • Creare un file MASM per aggiungere my_handler alla tabella SEH. Ma the SAFESEH example on MSN non ha funzionato sul mio portatile. Ho trovato questa soluzione su StackOverflow per funzionare invece: Custom SEH handler with /SAFESEH. Ma dobbiamo creare una procedura MASM addizionale per passare alla funzione C esterna.

+0

Hai assolutamente bisogno di quel file MASM? Non puoi semplicemente aggiungere quel codice assembly usando l'assembly inline? – Calmarius

+0

@Calmarius Dubito che se lavori in linea. C'è un parametro -safeseh passato a ml.exe, che non è supportato da cl.exe. Per tua informazione, ho compilato il comando asm utilizzando: ml.exe -Fo my.obj -c -safeseh my.asm – jichi