diff options
author | Jan Kotas <jkotas@microsoft.com> | 2017-01-25 04:45:59 +0300 |
---|---|---|
committer | Jan Kotas <jkotas@microsoft.com> | 2017-01-25 04:45:59 +0300 |
commit | 9271b7edd05f4f10dd25d8ab7a8402cd1e4a89cd (patch) | |
tree | 477972b5437e60dd5979a9a22cf02ddefd0f1ed1 /src/Native/Runtime/EHHelpers.cpp | |
parent | 30fc995b02807f7863cd6dde5d4944dc7ce7d0f2 (diff) |
Change stackwalking to always use unadjusted IP
Handling of hardware exceptions had a hack to add +1 to the actual instruction IP. Windows x64 unwinder
is disassembling instructions at the IP passed in to detect method epilogs. If the bytes at IP + 1
happened to match the epilog pattern, the unwind is done as if we were in the middle of the epilog that
lead to spectacular crash.
This change is moving this adjustment to be done later for EH related things only, and not interfere
with stackwalking.
Fixes #2535
[tfs-changeset: 1645602]
Diffstat (limited to 'src/Native/Runtime/EHHelpers.cpp')
-rw-r--r-- | src/Native/Runtime/EHHelpers.cpp | 24 |
1 files changed, 15 insertions, 9 deletions
diff --git a/src/Native/Runtime/EHHelpers.cpp b/src/Native/Runtime/EHHelpers.cpp index 65d8a6cb0..8c7dfb4d7 100644 --- a/src/Native/Runtime/EHHelpers.cpp +++ b/src/Native/Runtime/EHHelpers.cpp @@ -367,14 +367,11 @@ static UIntNative UnwindWriteBarrierToCaller( #endif #if defined(_AMD64_) || defined(_X86_) // simulate a ret instruction - UIntNative sp = pContext->GetSp(); // get the stack pointer - UIntNative adjustedFaultingIP = *(UIntNative *)sp - 5; // call instruction will be 6 bytes - act as if start of call instruction + 1 were the faulting IP + UIntNative sp = pContext->GetSp(); + UIntNative adjustedFaultingIP = *(UIntNative *)sp; pContext->SetSp(sp+sizeof(UIntNative)); // pop the stack -#elif defined(_ARM_) - UIntNative adjustedFaultingIP = pContext->GetLr() - 2; // bl instruction will be 4 bytes - act as if start of call instruction + 2 were the faulting IP -#elif defined(_ARM64_) - PORTABILITY_ASSERT("@TODO: FIXME:ARM64"); - UIntNative adjustedFaultingIP = -1; +#elif defined(_ARM_) || defined(_ARM64_) + UIntNative adjustedFaultingIP = pContext->GetLr(); #else #error "Unknown Architecture" #endif @@ -390,11 +387,14 @@ Int32 __stdcall RhpHardwareExceptionHandler(UIntNative faultCode, UIntNative fau ICodeManager * pCodeManager = GetRuntimeInstance()->FindCodeManagerByAddress((PTR_VOID)faultingIP); if ((pCodeManager != NULL) || (faultCode == STATUS_ACCESS_VIOLATION && InWriteBarrierHelper(faultingIP))) { + // Make sure that the OS does not use our internal fault codes + ASSERT(faultCode != STATUS_REDHAWK_NULL_REFERENCE && faultCode != STATUS_REDHAWK_WRITE_BARRIER_NULL_REFERENCE); + if (faultCode == STATUS_ACCESS_VIOLATION) { if (faultAddress < NULL_AREA_SIZE) { - faultCode = STATUS_REDHAWK_NULL_REFERENCE; + faultCode = pCodeManager ? STATUS_REDHAWK_NULL_REFERENCE : STATUS_REDHAWK_WRITE_BARRIER_NULL_REFERENCE; } if (pCodeManager == NULL) @@ -429,10 +429,16 @@ Int32 __stdcall RhpVectoredExceptionHandler(PEXCEPTION_POINTERS pExPtrs) UIntNative faultCode = pExPtrs->ExceptionRecord->ExceptionCode; if ((pCodeManager != NULL) || (faultCode == STATUS_ACCESS_VIOLATION && InWriteBarrierHelper(faultingIP))) { + // Make sure that the OS does not use our internal fault codes + ASSERT(faultCode != STATUS_REDHAWK_NULL_REFERENCE && faultCode != STATUS_REDHAWK_WRITE_BARRIER_NULL_REFERENCE); + if (faultCode == STATUS_ACCESS_VIOLATION) { if (pExPtrs->ExceptionRecord->ExceptionInformation[1] < NULL_AREA_SIZE) - faultCode = STATUS_REDHAWK_NULL_REFERENCE; + { + faultCode = pCodeManager ? STATUS_REDHAWK_NULL_REFERENCE : STATUS_REDHAWK_WRITE_BARRIER_NULL_REFERENCE; + } + if (pCodeManager == NULL) { // we were AV-ing in a write barrier helper - unwind our way to our caller |