Current wxMSW handling of WM_CLOSE seems to be a segfault trap. (Issue #22935)

61 views
Skip to first unread message

mcorino

unread,
Oct 31, 2022, 9:46:31 AM10/31/22
to wx-...@googlegroups.com, Subscribed

Description

I may be totally wrong here of course but it seems that the way the WM_CLOSE event is handled currently in toplevel windows (wxFrame/wxDialog) of the wxMSW port is a recipe waiting for disaster (i.e segfaults). And I think I ran into that disaster.

I am working on a Ruby wrapper for wxWidgets code and encountered some strange problems on Windows where an wxApp started through this wrapper would work just fine and would exit without problems when using the [Exit] menuitem of the app. When however using the windows system commands (press the [x] buton or choose [Close[ from the windows system menu or use Alt+F4) to exit the app it would segfault on exit.

I tracked this down to the fact that the latter exit options trigger App exit from the event sequence WM_SYSCOMMAND -> WM_CLOSE where the wxFrame::MSWWindowProc method will handle the WM_CLOSE message by calling the windows Close() method. It so however with this code:
processed = !Close();
This results in processed only being true whenever the close is vetoed which in turn causes wxWidgets in normal cases (when the window is actually closed and processed becomes false) to send the WM_CLOSE message down the inheritance chain of overloaded base methods until we reach wxWindow::MSWWindowProc where the wxWindow::MSWHandleMessage message is called.
This is however a virtual method and since the window in question has just been destroyed (that being the ultimate result of calling the Close method) that is the disaster waiting to happen. The calls down the inheritance chain I do not believe to access the virtual method tables but the call to wxWindow::MSWHandleMessage most certainly does and that is something you do NOT want to do on a destroyed object.

I have as yet not been able to reproduce this with any minimal wxWidgets samples. My Ruby wrapper however does some fairly complex cleanups when the toplevel window is destroyed (in an event handler of the wxApp attached to wxEVT_DESTROY) and that seems to cause enough changes on the heap that the destroyed wxFrame instances memory becomes sufficiently invalid to cause this segfault to happen.

I also tested by changing the code in wxFrame::MSWWindowProc to always set processed to true so it's not propagated anymore and with that change I see no segfaults anymore and the app exits cleanly.

Platform and version information

  • wxWidgets version you use: 3.2.1
  • wxWidgets port you use: wxMSW
  • OS and its version: Windows 10


Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you are subscribed to this thread.Message ID: <wxWidgets/wxWidgets/issues/22935@github.com>

mcorino

unread,
Oct 31, 2022, 11:21:14 AM10/31/22
to wx-...@googlegroups.com, Subscribed

Ah, bother. Reality is more complex than this. Forget it, I need to look at more things.


Reply to this email directly, view it on GitHub, or unsubscribe.

You are receiving this because you are subscribed to this thread.Message ID: <wxWidgets/wxWidgets/issues/22935/1297252021@github.com>

mcorino

unread,
Oct 31, 2022, 11:21:14 AM10/31/22
to wx-...@googlegroups.com, Subscribed

Closed #22935 as completed.


Reply to this email directly, view it on GitHub, or unsubscribe.

You are receiving this because you are subscribed to this thread.Message ID: <wxWidgets/wxWidgets/issue/22935/issue_event/7705373642@github.com>

VZ

unread,
Nov 8, 2022, 9:08:28 AM11/8/22
to wx-...@googlegroups.com, Subscribed

FWIW the C++ window object is definitely not supposed to be destroyed when the Windows window object (HWND) gets WM_CLOSE, so something went wrong before you got there.


Reply to this email directly, view it on GitHub, or unsubscribe.

You are receiving this because you are subscribed to this thread.Message ID: <wxWidgets/wxWidgets/issues/22935/1307278156@github.com>

Reply all
Reply to author
Forward
0 new messages