diff options
author | Jan Vorlicek <janvorli@microsoft.com> | 2016-05-23 20:22:35 +0200 |
---|---|---|
committer | Jan Vorlicek <janvorli@microsoft.com> | 2016-05-23 20:22:35 +0200 |
commit | 37d2c7bed790af03173bb66aeff37796cb25eb66 (patch) | |
tree | 9f12e1514e01a71163cf820f591a6148628b0e72 /src/vm/exceptionhandling.cpp | |
parent | a2d24aa4e65c8de05c1d760c4be7e7537378f3ed (diff) | |
download | coreclr-37d2c7bed790af03173bb66aeff37796cb25eb66.tar.gz coreclr-37d2c7bed790af03173bb66aeff37796cb25eb66.tar.bz2 coreclr-37d2c7bed790af03173bb66aeff37796cb25eb66.zip |
Change Unix HW exception unwinding to not to go through signal trampoline (#5140)
This change modifies the HW exception handling on Unix so that it doesn't unwind
from the context of the DispatchManagedException through the signal trampoline
to the actual location of the exception and uses the exception's context instead.
This fixes problem that some target systems like ARM Linux have with unwinding
through that trampoline.
Diffstat (limited to 'src/vm/exceptionhandling.cpp')
-rw-r--r-- | src/vm/exceptionhandling.cpp | 41 |
1 files changed, 28 insertions, 13 deletions
diff --git a/src/vm/exceptionhandling.cpp b/src/vm/exceptionhandling.cpp index 8d010e0354..58a796a1d1 100644 --- a/src/vm/exceptionhandling.cpp +++ b/src/vm/exceptionhandling.cpp @@ -4643,24 +4643,39 @@ VOID DECLSPEC_NORETURN DispatchManagedException(PAL_SEHException& ex) { // Unwind the context to the first managed frame CONTEXT frameContext; - RtlCaptureContext(&frameContext); - UINT_PTR currentSP = GetSP(&frameContext); - if (Thread::VirtualUnwindToFirstManagedCallFrame(&frameContext) == 0) + // See if the exception is a hardware one. In such case, we are either in jitted code + // or in a marked jit helper. + if (ex.ContextRecord.ContextFlags & CONTEXT_EXCEPTION_ACTIVE) { - // There are no managed frames on the stack, so we need to continue unwinding using C++ exception - // handling - break; + frameContext = ex.ContextRecord; + if (IsIPInMarkedJitHelper(GetIP(&frameContext))) + { + // Unwind to the managed caller of the helper + PAL_VirtualUnwind(&frameContext, NULL); + } } + else + { + RtlCaptureContext(&frameContext); + UINT_PTR currentSP = GetSP(&frameContext); + + if (Thread::VirtualUnwindToFirstManagedCallFrame(&frameContext) == 0) + { + // There are no managed frames on the stack, so we need to continue unwinding using C++ exception + // handling + break; + } - UINT_PTR firstManagedFrameSP = GetSP(&frameContext); + UINT_PTR firstManagedFrameSP = GetSP(&frameContext); - // Check if there is any exception holder in the skipped frames. If there is one, we need to unwind them - // using the C++ handling. This is a special case when the UNINSTALL_MANAGED_EXCEPTION_DISPATCHER was - // not at the managed to native boundary. - if (NativeExceptionHolderBase::FindNextHolder(nullptr, (void*)currentSP, (void*)firstManagedFrameSP) != nullptr) - { - break; + // Check if there is any exception holder in the skipped frames. If there is one, we need to unwind them + // using the C++ handling. This is a special case when the UNINSTALL_MANAGED_EXCEPTION_DISPATCHER was + // not at the managed to native boundary. + if (NativeExceptionHolderBase::FindNextHolder(nullptr, (void*)currentSP, (void*)firstManagedFrameSP) != nullptr) + { + break; + } } if (ex.IsFirstPass()) |