Skip to content

Commit c8980d5

Browse files
committed
Allow opting out of catching unhandled C++ exceptions
Add a system option to control whether the main loop and threads are run from within a try-catch block, or outside of it. Traditionally, wxWidgets has caught all unhandled C++ exceptions that are about to cause the program to be aborted. For many situations this is probably a good thing, but the downside is that it severely complicates debugging the source of such exceptions. The backtrace will only show the stack since wx's exception handler, but not where the exception occurred in the first place. Any crashdumps created by the OS also suffer from the same issue; backtraces are mostly useless in these cases. The following classes with try-catch blocks do not obey the new system option for now: wxDataViewRendererBase, wxDocTemplate, wxIDropTarget
1 parent 2a4a006 commit c8980d5

File tree

6 files changed

+48
-5
lines changed

6 files changed

+48
-5
lines changed

interface/wx/sysopt.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,15 @@
3737
this option allows changing it without modifying the program code and
3838
also applies to asserts which may happen before the wxApp object
3939
creation or after its destruction.
40+
@flag{catch-unhandled-exceptions}
41+
If set to zero, wxWidgets will not catch unhandled exceptions, but
42+
rather lets the default behavior of aborting the program take place.
43+
Not catching unhandled exceptions makes debugging easier, as the
44+
backtrace is more likely to show what actually happened, and where.
45+
The same applies to any crash dumps generated due to unhandled exceptions.
46+
By default unhandled exceptions are eventually caught by wxWidgets.
47+
This flag should be set very early during program startup, within
48+
the constructor of the wxApp derivative.
4049
@endFlagTable
4150
4251
@section sysopt_win Windows

src/common/event.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include "wx/event.h"
2323
#include "wx/eventfilter.h"
2424
#include "wx/evtloop.h"
25+
#include "wx/sysopt.h"
2526

2627
#ifndef WX_PRECOMP
2728
#include "wx/list.h"
@@ -1666,6 +1667,10 @@ bool wxEvtHandler::TryHereOnly(wxEvent& event)
16661667

16671668
bool wxEvtHandler::SafelyProcessEvent(wxEvent& event)
16681669
{
1670+
if ( wxSystemOptions::IsFalse("catch-unhandled-exceptions") )
1671+
{
1672+
return ProcessEvent(event);
1673+
}
16691674
#if wxUSE_EXCEPTIONS
16701675
try
16711676
{

src/common/evtloopcmn.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020

2121
#include "wx/scopeguard.h"
2222
#include "wx/apptrait.h"
23+
#include "wx/sysopt.h"
2324
#include "wx/private/eventloopsourcesmanager.h"
2425

2526
// Counts currently existing event loops.
@@ -342,6 +343,11 @@ int wxEventLoopManual::DoRun()
342343
// wxModalEventLoop depends on this (so we can't just use ON_BLOCK_EXIT or
343344
// something similar here)
344345
#if wxUSE_EXCEPTIONS
346+
if ( wxSystemOptions::IsFalse("catch-unhandled-exceptions") )
347+
{
348+
Loop();
349+
return m_exitcode;
350+
}
345351
for ( ;; )
346352
{
347353
try

src/common/init.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
#include "wx/atomic.h"
3030

3131
#include "wx/except.h"
32+
#include "wx/sysopt.h"
3233

3334
#if defined(__WINDOWS__)
3435
#include "wx/msw/private.h"
@@ -575,6 +576,10 @@ int wxEntryReal(int& argc, wxChar **argv)
575576
return wxApp::GetFatalErrorExitCode();
576577
}
577578

579+
if ( wxSystemOptions::IsFalse("catch-unhandled-exceptions") )
580+
{
581+
return DoEntryReal();
582+
}
578583
wxTRY
579584
{
580585
return DoEntryReal();

src/msw/thread.cpp

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838

3939
#include "wx/except.h"
4040
#include "wx/dynlib.h"
41+
#include "wx/sysopt.h"
4142

4243
// must have this symbol defined to get _beginthread/_endthread declarations
4344
#ifndef _MT
@@ -503,9 +504,13 @@ class wxThreadKeepAlive
503504
/* static */
504505
void wxThreadInternal::DoThreadOnExit(wxThread *thread)
505506
{
507+
if ( wxSystemOptions::IsFalse("catch-unhandled-exceptions") )
508+
{
509+
return thread->OnExit();
510+
}
506511
wxTRY
507512
{
508-
thread->OnExit();
513+
return thread->OnExit();
509514
}
510515
wxCATCH_ALL( wxTheApp->OnUnhandledException(); )
511516
}
@@ -532,15 +537,17 @@ THREAD_RETVAL wxThreadInternal::DoThreadStart(wxThread *thread)
532537
{
533538
wxON_BLOCK_EXIT1(DoThreadOnExit, thread);
534539

535-
THREAD_RETVAL rc = THREAD_ERROR_EXIT;
536-
540+
if ( wxSystemOptions::IsFalse("catch-unhandled-exceptions") )
541+
{
542+
return DoThreadStartWithoutExceptionHandling(thread);
543+
}
537544
wxTRY
538545
{
539-
rc = DoThreadStartWithoutExceptionHandling(thread);
546+
return DoThreadStartWithoutExceptionHandling(thread);
540547
}
541548
wxCATCH_ALL( wxTheApp->OnUnhandledException(); )
542549

543-
return rc;
550+
return THREAD_ERROR_EXIT;
544551
}
545552

546553
/* static */

src/unix/threadpsx.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727

2828
#include "wx/thread.h"
2929
#include "wx/except.h"
30+
#include "wx/sysopt.h"
3031

3132
#ifndef WX_PRECOMP
3233
#include "wx/app.h"
@@ -889,6 +890,11 @@ void *wxThreadInternal::PthreadStart(wxThread *thread)
889890
wxT("Thread %p about to enter its Entry()."),
890891
THR_ID(pthread));
891892

893+
if ( wxSystemOptions::IsFalse("catch-unhandled-exceptions") )
894+
{
895+
CallThreadEntryWithoutExceptionHandling(pthread, thread);
896+
}
897+
else
892898
wxTRY
893899
{
894900
CallThreadEntryWithoutExceptionHandling(pthread, thread);
@@ -1740,6 +1746,11 @@ void wxThread::Exit(ExitCode status)
17401746
// might deadlock if, for example, it signals a condition in OnExit() (a
17411747
// common case) while the main thread calls any of functions entering
17421748
// m_critsect on us (almost all of them do)
1749+
if ( wxSystemOptions::IsFalse("catch-unhandled-exceptions") )
1750+
{
1751+
OnExit();
1752+
}
1753+
else
17431754
wxTRY
17441755
{
17451756
OnExit();

0 commit comments

Comments
 (0)