[libunwind] fc5e68f - [libunwind] [SEH] Don't interact with foreign exceptions

Martin Storsjö via cfe-commits cfe-commits at lists.llvm.org
Mon Oct 12 13:28:38 PDT 2020


Author: Martin Storsjö
Date: 2020-10-12T23:28:22+03:00
New Revision: fc5e68fab965bdc8fdf6db9ae2603f9dd02dec5b

URL: https://github.com/llvm/llvm-project/commit/fc5e68fab965bdc8fdf6db9ae2603f9dd02dec5b
DIFF: https://github.com/llvm/llvm-project/commit/fc5e68fab965bdc8fdf6db9ae2603f9dd02dec5b.diff

LOG: [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

Added: 
    

Modified: 
    libunwind/src/Unwind-seh.cpp

Removed: 
    


################################################################################
diff  --git a/libunwind/src/Unwind-seh.cpp b/libunwind/src/Unwind-seh.cpp
index 403ab2d77110..6e2b4e73e41e 100644
--- a/libunwind/src/Unwind-seh.cpp
+++ b/libunwind/src/Unwind-seh.cpp
@@ -46,18 +46,6 @@ using namespace libunwind;
 /// handling.
 #define STATUS_GCC_UNWIND MAKE_GCC_EXCEPTION(1) // 0x21474343
 
-/// Class of foreign exceptions based on unrecognized SEH exceptions.
-static const uint64_t kSEHExceptionClass = 0x434C4E4753454800; // CLNGSEH\0
-
-/// Exception cleanup routine used by \c _GCC_specific_handler to
-/// free foreign exceptions.
-static void seh_exc_cleanup(_Unwind_Reason_Code urc, _Unwind_Exception *exc) {
-  (void)urc;
-  if (exc->exception_class != kSEHExceptionClass)
-    _LIBUNWIND_ABORT("SEH cleanup called on non-SEH exception");
-  free(exc);
-}
-
 static int __unw_init_seh(unw_cursor_t *cursor, CONTEXT *ctx);
 static DISPATCHER_CONTEXT *__unw_seh_get_disp_ctx(unw_cursor_t *cursor);
 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,
     }
   } else {
     // Foreign exception.
-    exc = (_Unwind_Exception *)malloc(sizeof(_Unwind_Exception));
-    exc->exception_class = kSEHExceptionClass;
-    exc->exception_cleanup = seh_exc_cleanup;
-    memset(exc->private_, 0, sizeof(exc->private_));
+    // We can't interact with them (we don't know the original target frame
+    // that we should pass on to RtlUnwindEx in _Unwind_Resume), so just
+    // pass without calling our destructors here.
+    return ExceptionContinueSearch;
   }
   if (!ctx) {
     __unw_init_seh(&cursor, disp->ContextRecord);


        


More information about the cfe-commits mailing list