Delete windows before application on session end in wxMSW

When WM_ENDSESSION was received by the application, the wxApp object
itself was shut down by calling OnExit() on it before all the TLWs were
destroyed, which could be completely unexpected as during normal
shutdown the order of events is exactly the reverse.

In practice, this resulted in crashes in any application whose main
window close event handler or dtor touched wxTheApp in any way (e.g. to
save any configuration in the global wxConfig object destroyed by
wxApp::OnExit()).

See #9590 (sorry for missing the point before, ATS).
This commit is contained in:
Vadim Zeitlin
2017-08-15 00:41:16 +02:00
parent 7316ce7626
commit 01fac4b748
3 changed files with 25 additions and 8 deletions

View File

@@ -127,6 +127,18 @@ wxAppBase::~wxAppBase()
// this destructor is required for Darwin
}
void wxAppBase::DeleteAllTLWs()
{
// TLWs remove themselves from wxTopLevelWindows when destroyed, so iterate
// until none are left.
while ( !wxTopLevelWindows.empty() )
{
// do not use Destroy() here as it only puts the TLW in pending list
// but we want to delete them now
delete wxTopLevelWindows.GetFirst()->GetData();
}
}
void wxAppBase::CleanUp()
{
// Clean up any still pending objects. Normally there shouldn't any as we
@@ -135,14 +147,8 @@ void wxAppBase::CleanUp()
// the base class OnExit().
DeletePendingObjects();
// and any remaining TLWs (they remove themselves from wxTopLevelWindows
// when destroyed, so iterate until none are left)
while ( !wxTopLevelWindows.empty() )
{
// do not use Destroy() here as it only puts the TLW in pending list
// but we want to delete them now
delete wxTopLevelWindows.GetFirst()->GetData();
}
// and any remaining TLWs
DeleteAllTLWs();
// undo everything we did in Initialize() above
wxBitmap::CleanUpHandlers();