Подтвердить что ты не робот

Почему Windows проглатывает исключения во время WM_CLOSE

При попытке выяснить, почему приложение, над которым я работаю, не закрывается, я понял, что он выбрал исключение в своем обработчике WM_CLOSE. Однако вместо сбоя приложения (как и должно быть) исключение игнорируется.

Чтобы убедиться, что ничего не происходит, я создал новое приложение С++ Win32 в Visual Studio и добавил следующее:

case WM_CLOSE:
    (*(int*)NULL) = 0;
    break;

То же самое: без сбоев, только исключение первого шанса в журнале отладки. Если я добавлю тот же код в обработчик WM_COMMAND, он сработает, как ожидалось.

Итак, мне любопытно: что такого особенного в WM_CLOSE, что Windows считает, что выбрасываемые им исключения должны быть проглочены?

(Кстати: это на Windows 7 x64, запущена программа x86)

4b9b3361

Ответ 1

Это исключение можно проглатывать с помощью WindowProc на Win 64. (См. документы.)

Также см. более подробные пояснения к Paul Betts, особенно его заметка

Почему так не происходит все время?

Вот почему это, похоже, происходит только в некоторых оконных сообщениях - помните, что оконные сообщения могут происходить из разных источников, любой (*) может поставить в очередь сообщение в окно. Однако определенное окно сообщения отправляются напрямую через win32k.sys(наиболее заметным из них является WM_CREATE) как прямой синхронный результат вызова пользовательского режима.

похоже, пролить свет на этот вопрос.

Случайный ASCII также имеет хорошее объяснение во всем этом явном режиме-экс-проглатывании:

Невозможность остановки вообще

Не менее тревожная проблема была введена несколько лет назад с 64-битные Windows, и это приводит к тому, что некоторые сбои игнорируются.

Структурированное исключение... полагается на возможность разматывать стек (без вызова деструкторов или без вызова) для передачи выполнение, из которого возникает исключение для блока catch/__ except.

Введение 64-битной Windows осложнило это. В 64-битной Windows невозможно развернуть стек по границе ядра. То есть, если... исключение выбрано в обратном вызове, который является должно быть обработано на другой стороне границы ядра, тогда Windows не может справиться с этим.

Это может показаться немного эзотерическим и маловероятным - запись обратных вызовов ядра похоже на редкую деятельность, но ее на самом деле довольно часто. В в частности, WindowProc - это обратный вызов, а часто, вызываемый ядро,...

И в качестве бонуса: см. здесь, на SO о том, почему.