Do our best to show messages logged during program startup/shutdown.

Use wxMessageOutputBest to show them even under Windows where programs usually don't have stderr at all and also don't disable log target auto-creation during shutdown as it's arguably better to leak memory (which shouldn't matter much when the program is about to exit anyhow) than to not show possibly important messages.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@61450 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin
2009-07-18 11:56:44 +00:00
parent e55919d892
commit 55b24eb8cd
2 changed files with 35 additions and 16 deletions

View File

@@ -229,13 +229,6 @@ static bool DoCommonPreInit()
#if wxUSE_LOG #if wxUSE_LOG
// Reset logging in case we were cleaned up and are being reinitialized. // Reset logging in case we were cleaned up and are being reinitialized.
wxLog::DoCreateOnDemand(); wxLog::DoCreateOnDemand();
// install temporary log sink: we can't use wxLogGui before wxApp is
// constructed and if we use wxLogStderr, all messages during
// initialization simply disappear under Windows
//
// note that we will delete this log target below
delete wxLog::SetActiveTarget(new wxLogBuffer);
#endif // wxUSE_LOG #endif // wxUSE_LOG
return true; return true;
@@ -356,14 +349,15 @@ bool wxEntryStart(int& argc, char **argv)
static void DoCommonPreCleanup() static void DoCommonPreCleanup()
{ {
#if wxUSE_LOG #if wxUSE_LOG
// flush the logged messages if any and install a 'safer' log target: the // flush the logged messages if any and don't use the current probably
// default one (wxLogGui) can't be used after the resources are freed just // unsafe log target any more: the default one (wxLogGui) can't be used
// below and the user supplied one might be even more unsafe (using any // after the resources are freed which happens when we return and the user
// wxWidgets GUI function is unsafe starting from now) // supplied one might be even more unsafe (using any wxWidgets GUI function
wxLog::DontCreateOnDemand(); // is unsafe starting from now)
//
// this will flush the old messages if any // notice that wxLog will still recreate a default log target if any
delete wxLog::SetActiveTarget(new wxLogStderr); // messages are logged but that one will be safe to use until the very end
delete wxLog::SetActiveTarget(NULL);
#endif // wxUSE_LOG #endif // wxUSE_LOG
} }
@@ -384,6 +378,12 @@ static void DoCommonPostCleanup()
#if wxUSE_LOG #if wxUSE_LOG
// and now delete the last logger as well // and now delete the last logger as well
//
// we still don't disable log target auto-vivification even if any log
// objects created now will result in memory leaks because it seems better
// to leak memory which doesn't matter much considering the application is
// exiting anyhow than to not show messages which could still be logged
// from the user code (e.g. static dtors and such)
delete wxLog::SetActiveTarget(NULL); delete wxLog::SetActiveTarget(NULL);
#endif // wxUSE_LOG #endif // wxUSE_LOG
} }

View File

@@ -165,6 +165,25 @@ PreviousLogInfo gs_prevLog;
// NB: all accesses to it must be protected by GetLevelsCS() critical section // NB: all accesses to it must be protected by GetLevelsCS() critical section
WX_DEFINE_GLOBAL_VAR(wxStringToNumHashMap, ComponentLevels); WX_DEFINE_GLOBAL_VAR(wxStringToNumHashMap, ComponentLevels);
// ----------------------------------------------------------------------------
// wxLogOutputBest: wxLog wrapper around wxMessageOutputBest
// ----------------------------------------------------------------------------
class wxLogOutputBest : public wxLog
{
public:
wxLogOutputBest() { }
protected:
virtual void DoLogText(const wxString& msg)
{
wxMessageOutputBest().Output(msg);
}
private:
wxDECLARE_NO_COPY_CLASS(wxLogOutputBest);
};
} // anonymous namespace } // anonymous namespace
// ============================================================================ // ============================================================================
@@ -481,7 +500,7 @@ wxLog *wxLog::GetMainThreadActiveTarget()
if ( wxTheApp != NULL ) if ( wxTheApp != NULL )
ms_pLogger = wxTheApp->GetTraits()->CreateLogTarget(); ms_pLogger = wxTheApp->GetTraits()->CreateLogTarget();
else else
ms_pLogger = new wxLogStderr; ms_pLogger = new wxLogOutputBest;
s_bInGetActiveTarget = false; s_bInGetActiveTarget = false;