2010-04-13 4 views
7

Следующий код будет давать жесткий сбой при запуске под Windows 7 32bit:исключения 64bit в WndProc молча терпеть неудачу

void CTestView::OnDraw(CDC* /*pDC*/) 
{ 
    *(int*)0 = 0; // Crash 

    CTestDoc* pDoc = GetDocument(); 
    ASSERT_VALID(pDoc); 
    if (!pDoc) 
     return; 

    // TODO: add draw code for native data here 
} 

Однако, если я пытаюсь это на Windows 7 64bit, я просто получить это в окне вывода :

первого шанса исключение в 0x13929384 в tEST.exe: 0xC0000005: нарушение прав доступа месте для записи 0x00000000.
первого шанса на исключение 0x77c6ee42 в test.exe: 0xC0150010: контекст активации деактивируется не активен для текущего потока исполнения.

В чем причина этого? Я знаю, что это аппаратное исключение (http://msdn.microsoft.com/en-us/library/aa363082.aspx), но почему разница при работе под 32 бит и 64 бит? И что я могу сделать, чтобы правильно обрабатывать такие ошибки? Поскольку они действительно должны быть пойманы в ловушку и исправлены, в отличие от того, что в настоящее время происходит, поскольку Windows просто переносит сообщения в приложение и запускает его (так что пользователь и разработчики совершенно не знают, что на самом деле возникли какие-либо проблемы).

Update: Наше обычное программное обеспечение аварии отчетов использует SetUnhandledExceptionFilter но не дозвонились на x64 для аппаратных исключений внутри WndProc. У кого-нибудь есть информация об этом или обходной путь?

Update2: Я сообщил о проблеме в Microsoft Connect:
https://connect.microsoft.com/VisualStudio/feedback/details/550944/hardware-exceptions-on-x64-machines-are-silently-caught-in-wndproc-messages

+0

Я не думаю, что просто компиляции для 64-битных вариант? – jalf

+0

Компиляция для x64 на самом деле не является опцией, наш исходный код состоит из примерно 1 миллион строк кода, а также значительного количества ассемблера. Объедините это с добавленной стоимостью для запуска двух отдельных сборок через QA и т. Д. –

+1

См. Также раздел замечаний [Функция обратного вызова WindowProc] (http://msdn.microsoft.com/en-us/library/windows/desktop/ms633573% 28v = vs.85% 29.aspx) – wimh

ответ

1

ОК, я получил ответ от Microsoft:

Здравствуйте,

Спасибо за отчет. Я обнаружил , что это проблема с Windows, и есть доступное исправление. Пожалуйста, см. http://support.microsoft.com/kb/976038 для исправления, которое вы можете установить, если вы желаете.

@Skute: обратите внимание, что программа Помощник по совместимости спросит раз , если программа должна быть предоставлена ​​возможность продолжать выполнять, и после того, что он всегда будет позволено, так что может быть причиной запутанным поведение вы посмотрели.

Pat Бреннер Visual C++ Библиотеки Разработка

Так что обходной путь либо убедитесь, что установлено исправление, или завернуть каждый WndProc в приложении с __try/__except блока.

+0

Не могли бы вы предоставить дополнительную информацию, где вы используете __try __except? Возможно ли исключить исключение из WindowProc в блоке catch в приложении C++. Об исправлении я устанавливаю DisableUserModeCallbackFilter в 1 в реестре, и лучше всего получаю FATAL_USER_CALLBACK_EXCEPTION, а не мое исключение. – Demion

+0

Вы используете '__try'' __except' в своей функции 'WNDPROC', или если вы используете MFC, который будет функцией' CWnd :: OnMsg' (я думаю, что это не в моей голове, может быть неправильно) , –

+0

Можно ли исключить исключение из WindowProc, а не ловить в WindowProc? – Demion

3

Там другое исключение поднимается, а стек разматывания за исключением нарушение прав доступа. Что проглатывается, в результате чего AV исчезает. Вам нужно будет выяснить, какой код это делает. Отладка + Исключения, установите флажок «Брошенный» для исключений Win32. Отладчик остановится на первом, продолжите. Проверьте стопку вызовов, когда он снова остановится. Добавьте его к своему вопросу, если вы не можете понять это.

+1

Исключение контекста активации возникает только при возникновении исключения AV. –

0

Единственный способ, которым нам удалось обойти эту проблему, - это поставить __try/__except вокруг каждого обратного вызова WndProc в приложении. Затем мы направляем исключение на наш обработчик исключений. Ужасно, но похоже, что это проблема с самой Windows. Все еще жду от Microsoft, чтобы вернуться к нам.

0

Я бы рискнул предположить, что проблема на самом деле связана с тем, как SEH работает в x64. Если ваше исключение должно возвращаться в режиме ядра, когда стек разматывается, то то, за что вы застряли, - это поведенческое поведение: The case of the disappearing OnLoad exception. Windows «обрабатывает» ваше исключение для вас; hot-fix является обходным решением для того, чтобы отдельные приложения для x64 могли работать, как x86.

0

Я сделал домашнюю работу, чтобы найти это: Исключение попадает в окна. Вот стеки и разборке:

stack and disassembling when wndproc get called

Смежные вопросы