2013-11-01 3 views
5

Читаю о Structured Exception Handling в C. Ниже приведен пример кода, который не работает, как ожидалось:Exception Handler не вызывается в C

Этот код взят отсюда:

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

Этот код должен печатать сообщение «Hello from my_handler», когда исключение запускается, пытаясь записать на неверный адрес памяти. Однако, похоже, обработчик исключений вообще не вызывается.

Я скомпилировал этот код и попытался отладить его с помощью Olly Debugger. Когда возникает исключение, я пытаюсь передать исключение в обработчик исключенных приложений (нажав Shift + F9), но он не вызван. Я установил точку останова в обработчике исключения (первая инструкция), но он никогда не доходит до этого раздела кода.

Что может быть причиной этого?

+0

Похоже, что это предупреждение компилятора, а не проверка ошибок во время выполнения. У меня нет окон, поэтому я не могу проверить .. – texasbruce

+0

Вы пытались скомпилировать свой код с параметрами компилятора '/ ZI/MTd'? Таким образом, у меня есть ожидаемый результат. – boleto

ответ

2

Я столкнулся с той же проблемой. Причина, по которой он не работает, заключается в том, что my_handler блокируется компилятором в указанное время. Нам нужно либо сообщить компилятору, что my_handler безопасен, либо полностью отключить проверку безопасности. Таким образом, есть два способа заставить его работать. (Пробовал как на MSVC 2008 и 2010)

  • Отключить SafeSEH таблицу ввода/SafeSEH: нет во время компоновки.

    cl /c C4733.cpp 
    link /safeseh:no C4733.obj 
    
  • Создайте файл MASM добавить my_handler к столу SEH. Но the SAFESEH example on MSN не работал на моем ноутбуке. Я нашел это решение вместо stackoverflow: Custom SEH handler with /SAFESEH. Но мы должны создать дополнительную процедуру MASM для перехода к внешней функции C.

+0

Вам нужен файл MASM? Не можете ли вы добавить этот ассемблерный код с помощью встроенной сборки? – Calmarius

+0

@Calmarius Я сомневаюсь, что работает inlining. Параметр -safeseh передается в файл ml.exe, который не поддерживается cl.exe. FYI, я составил asm, используя: ml.exe -Fo my.obj -c -safeseh my.asm – jichi