Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does Windows swallow exceptions during WM_CLOSE

While trying to figure out why an app I'm working on wouldn't close I realized it was throwing an exception in its WM_CLOSE handler. However instead of the app crashing (as it should), the exception gets silently ignored.

To make sure there wasn't something else going on, I created a new C++ Win32 app in Visual Studio and added this:

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

Same thing: no crash, just a first chance exception in the debug log. If I add the same code to a WM_COMMAND handler it crashes as expected.

So I'm curious: what's so special about WM_CLOSE that Windows deems exceptions thrown by it should be swallowed?

(BTW: this is on Windows 7 x64, running x86 program)

like image 588
Brad Robinson Avatar asked May 12 '14 07:05

Brad Robinson


Video Answer


1 Answers

That exceptions be swallowed by a WindowProc on Win 64 is expected behavior. (See docs.)

Also see the better explanations on Paul Betts' blog, especially his note

How come this doesn’t happen all the time?

Here’s why this seems to happen only on certain window messages – remember that window messages can originate from different sources, anyone(*) can queue a message to a window. However, certain window messages are directly sent via win32k.sys (the most notable one being WM_CREATE) as a direct synchronous result of a user-mode call.

seems to shed some light on this question.

Random ASCII also has some good explanation on all this kernel-mode-ex-swallowing behavior:

Failure to stop at all

An equally disturbing problem was introduced some years ago with 64-bit Windows and it causes some crashes to be silently ignored.

Structured exception ... relies on being able to unwind the stack (without or without calling destructors) in order to transfer execution from where an exception occurs to a catch/__except block.

The introduction of 64-bit Windows complicated this. On 64-bit Windows it is impossible to unwind the stack across the kernel boundary. That is, if ... an exception is thrown in the callback that is supposed to be handled on the other side of the kernel boundary, then Windows cannot handle this.

This may seem a bit esoteric and unlikely – writing kernel callbacks seems like a rare activity – but it’s actually quite common. In particular, a WindowProc is a callback, and it is often called by the kernel, ...

And as a bonus: See here on SO on the why.

like image 175
4 revs Avatar answered Sep 24 '22 21:09

4 revs