Skip to content

Commit fc5e68f

Browse files
committed
[libunwind] [SEH] Don't interact with foreign exceptions
This unfortunately means that we don't execute C++ destructors when unwinding past such frames for a different SEH unwind purpose (e.g. as part of setjmp/longjmp), but that case isn't handled properly at the moment (the original unwind intent is lost and we end up with an unhandled exception). This patch makes sure the foreign unwind terminates as intended. After executing a handler, _Unwind_Resume doesn't have access to the target frame parameter of the original foreign unwind. We also currently blindly set ExceptionCode to STATUS_GCC_THROW - we could set that correctly by storing the original code in _GCC_specific_handler, but we don't have access to the original target frame value. This also matches what libgcc's SEH unwinding code does in this case. Differential Revision: https://reviews.llvm.org/D89231
1 parent 8b6cd15 commit fc5e68f

File tree

1 file changed

+4
-16
lines changed

1 file changed

+4
-16
lines changed

libunwind/src/Unwind-seh.cpp

Lines changed: 4 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -46,18 +46,6 @@ using namespace libunwind;
4646
/// handling.
4747
#define STATUS_GCC_UNWIND MAKE_GCC_EXCEPTION(1) // 0x21474343
4848

49-
/// Class of foreign exceptions based on unrecognized SEH exceptions.
50-
static const uint64_t kSEHExceptionClass = 0x434C4E4753454800; // CLNGSEH\0
51-
52-
/// Exception cleanup routine used by \c _GCC_specific_handler to
53-
/// free foreign exceptions.
54-
static void seh_exc_cleanup(_Unwind_Reason_Code urc, _Unwind_Exception *exc) {
55-
(void)urc;
56-
if (exc->exception_class != kSEHExceptionClass)
57-
_LIBUNWIND_ABORT("SEH cleanup called on non-SEH exception");
58-
free(exc);
59-
}
60-
6149
static int __unw_init_seh(unw_cursor_t *cursor, CONTEXT *ctx);
6250
static DISPATCHER_CONTEXT *__unw_seh_get_disp_ctx(unw_cursor_t *cursor);
6351
static void __unw_seh_set_disp_ctx(unw_cursor_t *cursor,
@@ -108,10 +96,10 @@ _GCC_specific_handler(PEXCEPTION_RECORD ms_exc, PVOID frame, PCONTEXT ms_ctx,
10896
}
10997
} else {
11098
// Foreign exception.
111-
exc = (_Unwind_Exception *)malloc(sizeof(_Unwind_Exception));
112-
exc->exception_class = kSEHExceptionClass;
113-
exc->exception_cleanup = seh_exc_cleanup;
114-
memset(exc->private_, 0, sizeof(exc->private_));
99+
// We can't interact with them (we don't know the original target frame
100+
// that we should pass on to RtlUnwindEx in _Unwind_Resume), so just
101+
// pass without calling our destructors here.
102+
return ExceptionContinueSearch;
115103
}
116104
if (!ctx) {
117105
__unw_init_seh(&cursor, disp->ContextRecord);

0 commit comments

Comments
 (0)