summaryrefslogtreecommitdiff
path: root/src/vm/exceptionhandling.cpp
diff options
context:
space:
mode:
authorJan Vorlicek <janvorli@microsoft.com>2016-05-23 20:22:35 +0200
committerJan Vorlicek <janvorli@microsoft.com>2016-05-23 20:22:35 +0200
commit37d2c7bed790af03173bb66aeff37796cb25eb66 (patch)
tree9f12e1514e01a71163cf820f591a6148628b0e72 /src/vm/exceptionhandling.cpp
parenta2d24aa4e65c8de05c1d760c4be7e7537378f3ed (diff)
downloadcoreclr-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.cpp41
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())