Skip to content

Commit 9fe14c1

Browse files
committed
Fix reentrant exception handling.
Store handled status in local that is passed into handler rather than a single thread local value which can be overwritten in case of reentrance.
1 parent a1597e0 commit 9fe14c1

File tree

7 files changed

+26
-22
lines changed

7 files changed

+26
-22
lines changed

mono/mini/exceptions-amd64.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ LPTOP_LEVEL_EXCEPTION_FILTER mono_old_win_toplevel_exception_filter;
5858
void *mono_win_vectored_exception_handle;
5959

6060
#define W32_SEH_HANDLE_EX(_ex) \
61-
if (_ex##_handler) _ex##_handler(0, ep, ctx)
61+
if (_ex##_handler) _ex##_handler(er->ExceptionCode, &info, ctx)
6262

6363
static LONG CALLBACK seh_unhandled_exception_filter(EXCEPTION_POINTERS* ep)
6464
{
@@ -137,12 +137,12 @@ LONG CALLBACK seh_vectored_exception_handler(EXCEPTION_POINTERS* ep)
137137
LONG res;
138138
MonoJitTlsData *jit_tls = mono_tls_get_jit_tls ();
139139
MonoDomain* domain = mono_domain_get ();
140+
MonoWindowsSigHandlerInfo info = { TRUE, ep };
140141

141142
/* If the thread is not managed by the runtime return early */
142143
if (!jit_tls)
143144
return EXCEPTION_CONTINUE_SEARCH;
144145

145-
jit_tls->mono_win_chained_exception_needs_run = FALSE;
146146
res = EXCEPTION_CONTINUE_EXECUTION;
147147

148148
er = ep->ExceptionRecord;
@@ -159,7 +159,7 @@ LONG CALLBACK seh_vectored_exception_handler(EXCEPTION_POINTERS* ep)
159159
ctx->Rip = (guint64)restore_stack;
160160
}
161161
} else {
162-
jit_tls->mono_win_chained_exception_needs_run = TRUE;
162+
info.handled = FALSE;
163163
}
164164
break;
165165
case EXCEPTION_ACCESS_VIOLATION:
@@ -177,11 +177,11 @@ LONG CALLBACK seh_vectored_exception_handler(EXCEPTION_POINTERS* ep)
177177
W32_SEH_HANDLE_EX(fpe);
178178
break;
179179
default:
180-
jit_tls->mono_win_chained_exception_needs_run = TRUE;
180+
info.handled = FALSE;
181181
break;
182182
}
183183

184-
if (jit_tls->mono_win_chained_exception_needs_run) {
184+
if (!info.handled) {
185185
/* Don't copy context back if we chained exception
186186
* as the handler may have modfied the EXCEPTION_POINTERS
187187
* directly. We don't pass sigcontext to chained handlers.

mono/mini/exceptions-x86.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ extern int (*gUnhandledExceptionHandler)(EXCEPTION_POINTERS*);
5555
#endif
5656

5757
#define W32_SEH_HANDLE_EX(_ex) \
58-
if (_ex##_handler) _ex##_handler(0, ep, ctx)
58+
if (_ex##_handler) _ex##_handler(er->ExceptionCode, &info, ctx)
5959

6060
LONG CALLBACK seh_unhandled_exception_filter(EXCEPTION_POINTERS* ep)
6161
{
@@ -198,12 +198,12 @@ LONG CALLBACK seh_vectored_exception_handler(EXCEPTION_POINTERS* ep)
198198
CONTEXT* ctx;
199199
LONG res;
200200
MonoJitTlsData *jit_tls = mono_tls_get_jit_tls ();
201+
MonoWindowsSigHandlerInfo info = { TRUE, ep };
201202

202203
/* If the thread is not managed by the runtime return early */
203204
if (!jit_tls)
204205
return EXCEPTION_CONTINUE_SEARCH;
205206

206-
jit_tls->mono_win_chained_exception_needs_run = FALSE;
207207
res = EXCEPTION_CONTINUE_EXECUTION;
208208

209209
er = ep->ExceptionRecord;
@@ -228,11 +228,11 @@ LONG CALLBACK seh_vectored_exception_handler(EXCEPTION_POINTERS* ep)
228228
W32_SEH_HANDLE_EX(fpe);
229229
break;
230230
default:
231-
jit_tls->mono_win_chained_exception_needs_run = TRUE;
231+
info.handled = FALSE;
232232
break;
233233
}
234234

235-
if (jit_tls->mono_win_chained_exception_needs_run) {
235+
if (!info.handled) {
236236
/* Don't copy context back if we chained exception
237237
* as the handler may have modfied the EXCEPTION_POINTERS
238238
* directly. We don't pass sigcontext to chained handlers.

mono/mini/mini-amd64.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
#include <mono/arch/amd64/amd64-codegen.h>
99
#include <mono/utils/mono-sigcontext.h>
10+
#include <mono/utils/mono-signal-handler.h>
1011
#include <mono/utils/mono-context.h>
1112
#include <glib.h>
1213

@@ -32,7 +33,7 @@ struct sigcontext {
3233
};
3334
#endif
3435

35-
typedef void (* MonoW32ExceptionHandler) (int _dummy, EXCEPTION_POINTERS *info, void *context);
36+
typedef void MONO_SIG_HANDLER_SIGNATURE ((*MonoW32ExceptionHandler));
3637
void win32_seh_init(void);
3738
void win32_seh_cleanup(void);
3839
void win32_seh_set_handler(int type, MonoW32ExceptionHandler handler);

mono/mini/mini-runtime.h

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -101,11 +101,6 @@ struct MonoJitTlsData {
101101
MonoContext orig_ex_ctx;
102102
gboolean orig_ex_ctx_set;
103103

104-
/*
105-
* Stores if we need to run a chained exception in Windows.
106-
*/
107-
gboolean mono_win_chained_exception_needs_run;
108-
109104
/*
110105
* The current exception in flight
111106
*/

mono/mini/mini-windows.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -255,8 +255,8 @@ mono_runtime_cleanup_handlers (void)
255255
gboolean
256256
MONO_SIG_HANDLER_SIGNATURE (mono_chain_signal)
257257
{
258-
MonoJitTlsData *jit_tls = mono_tls_get_jit_tls ();
259-
jit_tls->mono_win_chained_exception_needs_run = TRUE;
258+
/* Set to FALSE to indicate that vectored exception handling should continue to look for handler */
259+
MONO_SIG_HANDLER_GET_INFO ()->handled = FALSE;
260260
return TRUE;
261261
}
262262

mono/mini/mini-x86.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
#include <signal.h>
1717
#endif
1818

19-
typedef void (* MonoW32ExceptionHandler) (int _dummy, EXCEPTION_POINTERS *info, void *context);
19+
typedef void MONO_SIG_HANDLER_SIGNATURE ((*MonoW32ExceptionHandler));
2020

2121
void win32_seh_init(void);
2222
void win32_seh_cleanup(void);

mono/utils/mono-signal-handler.h

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -78,12 +78,20 @@
7878
*/
7979

8080
#ifdef HOST_WIN32
81-
#define MONO_SIG_HANDLER_SIGNATURE(ftn) ftn (int _dummy, EXCEPTION_POINTERS *_info, void *context)
82-
#define MONO_SIG_HANDLER_FUNC(access, ftn) MONO_SIGNAL_HANDLER_FUNC (access, ftn, (int _dummy, EXCEPTION_POINTERS *_info, void *context))
81+
#define MONO_SIG_HANDLER_SIGNATURE(ftn) ftn (int _dummy, MonoWindowsSigHandlerInfo *_info, void *context)
82+
#define MONO_SIG_HANDLER_FUNC(access, ftn) MONO_SIGNAL_HANDLER_FUNC (access, ftn, (int _dummy, MonoWindowsSigHandlerInfo *_info, void *context))
8383
#define MONO_SIG_HANDLER_PARAMS _dummy, _info, context
84-
#define MONO_SIG_HANDLER_GET_SIGNO() (_dummy)
84+
#define MONO_SIG_HANDLER_GET_SIGNO() (0)
8585
#define MONO_SIG_HANDLER_GET_INFO() (_info)
86-
#define MONO_SIG_HANDLER_INFO_TYPE EXCEPTION_POINTERS
86+
#define MONO_SIG_HANDLER_INFO_TYPE MonoWindowsSigHandlerInfo
87+
typedef struct {
88+
/* Set to FALSE to indicate chained signal handler needs run.
89+
* With vectored exceptions Windows does that for us by returning
90+
* EXCEPTION_CONTINUE_SEARCH from handler */
91+
gboolean handled;
92+
EXCEPTION_POINTERS* ep;
93+
} MonoWindowsSigHandlerInfo;
94+
8795
/* seh_vectored_exception_handler () passes in a CONTEXT* */
8896
#define MONO_SIG_HANDLER_GET_CONTEXT \
8997
void *ctx = context;

0 commit comments

Comments
 (0)