fix dwarf-based unwinding to the end of stack
authorYaroslav Yamshchikov <y.yamshchiko@samsung.com>
Fri, 18 Sep 2020 12:25:21 +0000 (15:25 +0300)
committer이형주/Common Platform Lab(SR)/Staff Engineer/삼성전자 <leee.lee@samsung.com>
Mon, 5 Oct 2020 00:53:20 +0000 (09:53 +0900)
We experience CLR crash on some architectures (at least on x86) in case
of unhandled managed exception. libunwind steps to the very end of a
stack, and if .eh_frame info is correct, it returns with retcode 0 and
ip=0 from unw_step, then PAL calls unw_is_signal_frame with
c->validate==0 which in turn dereferences zeroed ip in access_mem.
libunwind spec says that retcode 0 from unw_step means very end of a
stack, so PAL should not expect any frames, signal or not. It should
convert cursor back to SEH representation and return with TRUE.

corresponding PR to dotnet/runtime on upstream:
https://github.com/dotnet/runtime/pull/42620

src/pal/src/exception/seh-unwind.cpp

index 3f40057..c5d0341 100644 (file)
@@ -314,7 +314,7 @@ BOOL PAL_VirtualUnwind(CONTEXT *context, KNONVOLATILE_CONTEXT_POINTERS *contextP
     // Check if the frame we have unwound to is a frame that caused
     // synchronous signal, like a hardware exception and record it
     // in the context flags.
-    if (unw_is_signal_frame(&cursor) > 0)
+    if ((st != 0) && (unw_is_signal_frame(&cursor) > 0))
     {
         context->ContextFlags |= CONTEXT_EXCEPTION_ACTIVE;
 #if defined(_ARM_) || defined(_ARM64_) || defined(_X86_)