From 90e9614bec11383f40a135625ac9f68f9f8a36c8 Mon Sep 17 00:00:00 2001 From: Santiago Fernandez Madero Date: Tue, 11 Feb 2020 19:11:27 -0800 Subject: [PATCH] Revert "Display stack trace at stack overflow (#31956)" (#32153) This reverts commit 65587ba7b402411b62ce877ee044aef2c2c71dfd. --- src/coreclr/src/debug/ee/controller.cpp | 2 +- src/coreclr/src/inc/ex.h | 2 +- .../src/arch/amd64/signalhandlerhelper.cpp | 20 +- .../pal/src/arch/arm/signalhandlerhelper.cpp | 18 +- .../src/arch/arm64/signalhandlerhelper.cpp | 17 +- .../pal/src/arch/i386/signalhandlerhelper.cpp | 16 +- src/coreclr/src/pal/src/exception/seh.cpp | 15 +- src/coreclr/src/pal/src/exception/signal.cpp | 108 +++-------- .../src/pal/src/include/pal/signal.hpp | 9 +- src/coreclr/src/pal/src/thread/thread.cpp | 2 +- src/coreclr/src/utilcode/ex.cpp | 4 +- src/coreclr/src/vm/amd64/JitHelpers_Fast.asm | 2 +- src/coreclr/src/vm/amd64/jithelpers_fast.S | 4 +- src/coreclr/src/vm/arm/asmhelpers.S | 4 +- src/coreclr/src/vm/arm/asmhelpers.asm | 4 +- src/coreclr/src/vm/eedbginterface.h | 2 +- src/coreclr/src/vm/eedbginterfaceimpl.cpp | 6 +- src/coreclr/src/vm/eedbginterfaceimpl.h | 2 +- src/coreclr/src/vm/eepolicy.cpp | 178 ++++-------------- src/coreclr/src/vm/excep.cpp | 30 +-- src/coreclr/src/vm/excep.h | 2 - src/coreclr/src/vm/exceptionhandling.cpp | 8 - src/coreclr/src/vm/frames.cpp | 3 +- src/coreclr/src/vm/i386/jithelp.S | 12 +- src/coreclr/src/vm/i386/jithelp.asm | 19 +- src/coreclr/src/vm/stackwalk.cpp | 4 +- src/coreclr/src/vm/threads.cpp | 12 +- src/coreclr/src/vm/threads.h | 19 +- 28 files changed, 133 insertions(+), 391 deletions(-) diff --git a/src/coreclr/src/debug/ee/controller.cpp b/src/coreclr/src/debug/ee/controller.cpp index 137fcf774067d..03b27612e5a5e 100644 --- a/src/coreclr/src/debug/ee/controller.cpp +++ b/src/coreclr/src/debug/ee/controller.cpp @@ -8961,7 +8961,7 @@ bool DebuggerContinuableExceptionBreakpoint::SendEvent(Thread *thread, bool fIpC CONTEXT contextToAdjust; BOOL adjustedContext = FALSE; memcpy(&contextToAdjust, pContext, sizeof(CONTEXT)); - adjustedContext = g_pEEInterface->AdjustContextForJITHelpersForDebugger(&contextToAdjust); + adjustedContext = g_pEEInterface->AdjustContextForWriteBarrierForDebugger(&contextToAdjust); if (adjustedContext) { LOG((LF_CORDB, LL_INFO10000, "D::DDBP: HIT DATA BREAKPOINT INSIDE WRITE BARRIER...\n")); diff --git a/src/coreclr/src/inc/ex.h b/src/coreclr/src/inc/ex.h index 21ce9d3d4b0ec..4037e51cd0ad3 100644 --- a/src/coreclr/src/inc/ex.h +++ b/src/coreclr/src/inc/ex.h @@ -112,7 +112,7 @@ void GenerateTopLevelHRExceptionMessage(HRESULT hresult, SString &result); // We save current ExceptionPointers using VectoredExceptionHandler. The save data is only valid // duing exception handling. GetCurrentExceptionPointers returns the saved data. // --------------------------------------------------------------------------- -void GetCurrentExceptionPointers(PEXCEPTION_POINTERS pExceptionInfo DEBUG_ARG(bool checkExceptionRecordLocation)); +void GetCurrentExceptionPointers(PEXCEPTION_POINTERS pExceptionInfo); // --------------------------------------------------------------------------- // We save current ExceptionPointers using VectoredExceptionHandler. The save data is only valid diff --git a/src/coreclr/src/pal/src/arch/amd64/signalhandlerhelper.cpp b/src/coreclr/src/pal/src/arch/amd64/signalhandlerhelper.cpp index 61eba90008d95..28232251b1318 100644 --- a/src/coreclr/src/pal/src/arch/amd64/signalhandlerhelper.cpp +++ b/src/coreclr/src/pal/src/arch/amd64/signalhandlerhelper.cpp @@ -13,11 +13,10 @@ SET_DEFAULT_DEBUG_CHANNEL(EXCEPT); // some headers have code with asserts, so do /*++ Function : - ExecuteHandlerOnCustomStack + signal_handler_worker - Execute signal handler on a custom stack, the current stack pointer is specified by the customSp - If the customSp is 0, then the handler is executed on the original stack where the signal was fired. - It installs a fake stack frame to enable stack unwinding to the signal source location. + Handles signal on the original stack where the signal occured. + Invoked via setcontext. Parameters : POSIX signal handler parameter list ("man sigaction" for details) @@ -25,19 +24,13 @@ Parameters : (no return value) --*/ -void ExecuteHandlerOnCustomStack(int code, siginfo_t *siginfo, void *context, size_t customSp, SignalHandlerWorkerReturnPoint* returnPoint) +void ExecuteHandlerOnOriginalStack(int code, siginfo_t *siginfo, void *context, SignalHandlerWorkerReturnPoint* returnPoint) { ucontext_t *ucontext = (ucontext_t *)context; size_t faultSp = (size_t)MCREG_Rsp(ucontext->uc_mcontext); _ASSERTE(IS_ALIGNED(faultSp, 8)); - if (customSp == 0) - { - // preserve 128 bytes long red zone and align stack pointer - customSp = ALIGN_DOWN(faultSp - 128, 16); - } - size_t fakeFrameReturnAddress; if (IS_ALIGNED(faultSp, 16)) @@ -49,7 +42,8 @@ void ExecuteHandlerOnCustomStack(int code, siginfo_t *siginfo, void *context, si fakeFrameReturnAddress = (size_t)SignalHandlerWorkerReturnOffset8 + (size_t)CallSignalHandlerWrapper8; } - size_t* sp = (size_t*)customSp; + // preserve 128 bytes long red zone and align stack pointer + size_t* sp = (size_t*)ALIGN_DOWN(faultSp - 128, 16); // Build fake stack frame to enable the stack unwinder to unwind from signal_handler_worker to the faulting instruction *--sp = (size_t)MCREG_Rip(ucontext->uc_mcontext); @@ -57,7 +51,7 @@ void ExecuteHandlerOnCustomStack(int code, siginfo_t *siginfo, void *context, si size_t fp = (size_t)sp; *--sp = fakeFrameReturnAddress; - // Switch the current context to the signal_handler_worker and the custom stack + // Switch the current context to the signal_handler_worker and the original stack CONTEXT context2; RtlCaptureContext(&context2); diff --git a/src/coreclr/src/pal/src/arch/arm/signalhandlerhelper.cpp b/src/coreclr/src/pal/src/arch/arm/signalhandlerhelper.cpp index 9c6dda1f2fb7b..eac3b29b81df8 100644 --- a/src/coreclr/src/pal/src/arch/arm/signalhandlerhelper.cpp +++ b/src/coreclr/src/pal/src/arch/arm/signalhandlerhelper.cpp @@ -13,11 +13,10 @@ SET_DEFAULT_DEBUG_CHANNEL(EXCEPT); // some headers have code with asserts, so do /*++ Function : - ExecuteHandlerOnCustomStack + signal_handler_worker - Execute signal handler on a custom stack, the current stack pointer is specified by the customSp - If the customSp is 0, then the handler is executed on the original stack where the signal was fired. - It installs a fake stack frame to enable stack unwinding to the signal source location. + Handles signal on the original stack where the signal occured. + Invoked via setcontext. Parameters : POSIX signal handler parameter list ("man sigaction" for details) @@ -25,19 +24,13 @@ Parameters : (no return value) --*/ -void ExecuteHandlerOnCustomStack(int code, siginfo_t *siginfo, void *context, size_t customSp, SignalHandlerWorkerReturnPoint* returnPoint) +void ExecuteHandlerOnOriginalStack(int code, siginfo_t *siginfo, void *context, SignalHandlerWorkerReturnPoint* returnPoint) { ucontext_t *ucontext = (ucontext_t *)context; size_t faultSp = (size_t)MCREG_Sp(ucontext->uc_mcontext); _ASSERTE(IS_ALIGNED(faultSp, 4)); - if (customSp == 0) - { - // preserve 8 bytes long red zone and align stack pointer - customSp = ALIGN_DOWN(faultSp - 8, 8); - } - size_t fakeFrameReturnAddress; if (IS_ALIGNED(faultSp, 8)) @@ -49,7 +42,8 @@ void ExecuteHandlerOnCustomStack(int code, siginfo_t *siginfo, void *context, si fakeFrameReturnAddress = (size_t)SignalHandlerWorkerReturnOffset4 + (size_t)CallSignalHandlerWrapper4; } - size_t* sp = (size_t*)customSp; + // preserve 8 bytes long red zone and align stack pointer + size_t* sp = (size_t*)ALIGN_DOWN(faultSp - 8, 8); #ifndef __linux__ size_t cpsr = (size_t)MCREG_Cpsr(ucontext->uc_mcontext); diff --git a/src/coreclr/src/pal/src/arch/arm64/signalhandlerhelper.cpp b/src/coreclr/src/pal/src/arch/arm64/signalhandlerhelper.cpp index 524bd11b364f8..b52e8a64d19af 100644 --- a/src/coreclr/src/pal/src/arch/arm64/signalhandlerhelper.cpp +++ b/src/coreclr/src/pal/src/arch/arm64/signalhandlerhelper.cpp @@ -13,11 +13,10 @@ SET_DEFAULT_DEBUG_CHANNEL(EXCEPT); // some headers have code with asserts, so do /*++ Function : - ExecuteHandlerOnCustomStack + signal_handler_worker - Execute signal handler on a custom stack, the current stack pointer is specified by the customSp - If the customSp is 0, then the handler is executed on the original stack where the signal was fired. - It installs a fake stack frame to enable stack unwinding to the signal source location. + Handles signal on the original stack where the signal occured. + Invoked via setcontext. Parameters : POSIX signal handler parameter list ("man sigaction" for details) @@ -25,18 +24,12 @@ Parameters : (no return value) --*/ -void ExecuteHandlerOnCustomStack(int code, siginfo_t *siginfo, void *context, size_t customSp, SignalHandlerWorkerReturnPoint* returnPoint) +void ExecuteHandlerOnOriginalStack(int code, siginfo_t *siginfo, void *context, SignalHandlerWorkerReturnPoint* returnPoint) { ucontext_t *ucontext = (ucontext_t *)context; size_t faultSp = (size_t)MCREG_Sp(ucontext->uc_mcontext); _ASSERTE(IS_ALIGNED(faultSp, 8)); - if (customSp == 0) - { - // preserve 128 bytes long red zone and align stack pointer - customSp = ALIGN_DOWN(faultSp - 128, 16); - } - size_t fakeFrameReturnAddress; if (IS_ALIGNED(faultSp, 16)) @@ -49,7 +42,7 @@ void ExecuteHandlerOnCustomStack(int code, siginfo_t *siginfo, void *context, si } // preserve 128 bytes long red zone and align stack pointer - size_t* sp = (size_t*)customSp; + size_t* sp = (size_t*)ALIGN_DOWN(faultSp - 128, 16); // Build fake stack frame to enable the stack unwinder to unwind from signal_handler_worker to the faulting instruction // pushed LR diff --git a/src/coreclr/src/pal/src/arch/i386/signalhandlerhelper.cpp b/src/coreclr/src/pal/src/arch/i386/signalhandlerhelper.cpp index 16e527a1ebcb8..8e23099193028 100644 --- a/src/coreclr/src/pal/src/arch/i386/signalhandlerhelper.cpp +++ b/src/coreclr/src/pal/src/arch/i386/signalhandlerhelper.cpp @@ -13,11 +13,10 @@ SET_DEFAULT_DEBUG_CHANNEL(EXCEPT); // some headers have code with asserts, so do /*++ Function : - ExecuteHandlerOnCustomStack + signal_handler_worker - Execute signal handler on a custom stack, the current stack pointer is specified by the customSp - If the customSp is 0, then the handler is executed on the original stack where the signal was fired. - It installs a fake stack frame to enable stack unwinding to the signal source location. + Handles signal on the original stack where the signal occured. + Invoked via setcontext. Parameters : POSIX signal handler parameter list ("man sigaction" for details) @@ -25,18 +24,13 @@ Parameters : (no return value) --*/ -void ExecuteHandlerOnCustomStack(int code, siginfo_t *siginfo, void *context, size_t customSp, SignalHandlerWorkerReturnPoint* returnPoint) +void ExecuteHandlerOnOriginalStack(int code, siginfo_t *siginfo, void *context, SignalHandlerWorkerReturnPoint* returnPoint) { ucontext_t *ucontext = (ucontext_t *)context; size_t faultSp = (size_t)MCREG_Esp(ucontext->uc_mcontext); _ASSERTE(IS_ALIGNED(faultSp, 4)); - if (customSp == 0) - { - customSp = ALIGN_DOWN(faultSp, 16); - } - size_t fakeFrameReturnAddress; switch (faultSp & 0xc) @@ -55,7 +49,7 @@ void ExecuteHandlerOnCustomStack(int code, siginfo_t *siginfo, void *context, si break; } - size_t* sp = (size_t*)customSp; + size_t* sp = (size_t*)ALIGN_DOWN(faultSp, 16); // Build fake stack frame to enable the stack unwinder to unwind from signal_handler_worker to the faulting instruction *--sp = (size_t)MCREG_Eip(ucontext->uc_mcontext); diff --git a/src/coreclr/src/pal/src/exception/seh.cpp b/src/coreclr/src/pal/src/exception/seh.cpp index e0ebff145b893..ef95f5e354a3d 100644 --- a/src/coreclr/src/pal/src/exception/seh.cpp +++ b/src/coreclr/src/pal/src/exception/seh.cpp @@ -28,7 +28,6 @@ Module Name: #include "pal/process.h" #include "pal/malloc.hpp" #include "pal/signal.hpp" -#include "pal/virtual.h" #if HAVE_MACH_EXCEPTIONS #include "machexception.h" @@ -269,16 +268,14 @@ SEHProcessException(PAL_SEHException* exception) // Check if the failed access has hit a stack guard page. In such case, it // was a stack probe that detected that there is not enough stack left. void* stackLimit = CPalThread::GetStackLimit(); - void* stackOverflowBottom = (void*)((size_t)stackLimit - GetVirtualPageSize()); - // On some versions of glibc / platforms the stackLimit is an address of the guard page, on some - // it is right above the guard page. - // So consider SIGSEGV in one page above and below stack limit to be stack overflow. - void* stackOverflowTop = (void*)((size_t)stackLimit + GetVirtualPageSize()); + void* stackGuard = (void*)((size_t)stackLimit - getpagesize()); void* violationAddr = (void*)exceptionRecord->ExceptionInformation[1]; - - if ((violationAddr >= stackOverflowBottom) && (violationAddr < stackOverflowTop)) + if ((violationAddr >= stackGuard) && (violationAddr < stackLimit)) { - exceptionRecord->ExceptionCode = EXCEPTION_STACK_OVERFLOW; + // The exception happened in the page right below the stack limit, + // so it is a stack overflow + (void)write(STDERR_FILENO, StackOverflowMessage, sizeof(StackOverflowMessage) - 1); + PROCAbort(); } } diff --git a/src/coreclr/src/pal/src/exception/signal.cpp b/src/coreclr/src/pal/src/exception/signal.cpp index d6d8256610e5c..49fdec8db89e4 100644 --- a/src/coreclr/src/pal/src/exception/signal.cpp +++ b/src/coreclr/src/pal/src/exception/signal.cpp @@ -113,9 +113,6 @@ struct sigaction g_previous_activation; // Offset of the local variable containing pointer to windows style context in the common_signal_handler function. // This offset is relative to the frame pointer. int g_common_signal_handler_context_locvar_offset = 0; - -// TOP of special stack for handling stack overflow -volatile void* g_stackOverflowHandlerStack = NULL; #endif // !HAVE_MACH_EXCEPTIONS /* public function definitions ************************************************/ @@ -178,26 +175,6 @@ BOOL SEHInitializeSignals(CorUnix::CPalThread *pthrCurrent, DWORD flags) { return FALSE; } - - // Allocate the minimal stack necessary for handling stack overflow - int stackOverflowStackSize = ALIGN_UP(sizeof(SignalHandlerWorkerReturnPoint), 16) + 7 * 4096; - // Align the size to virtual page size and add one virtual page as a stack guard - stackOverflowStackSize = ALIGN_UP(stackOverflowStackSize, GetVirtualPageSize()) + GetVirtualPageSize(); - g_stackOverflowHandlerStack = mmap(NULL, stackOverflowStackSize, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_STACK | MAP_PRIVATE, -1, 0); - if (g_stackOverflowHandlerStack == MAP_FAILED) - { - return FALSE; - } - - // create a guard page for the alternate stack - int st = mprotect((void*)g_stackOverflowHandlerStack, GetVirtualPageSize(), PROT_NONE); - if (st != 0) - { - munmap((void*)g_stackOverflowHandlerStack, stackOverflowStackSize); - return FALSE; - } - - g_stackOverflowHandlerStack = (void*)((size_t)g_stackOverflowHandlerStack + stackOverflowStackSize); } /* The default action for SIGPIPE is process termination. @@ -453,41 +430,6 @@ bool IsRunningOnAlternateStack(void *context) return isRunningOnAlternateStack; } -/*++ -Function : - SwitchStackAndExecuteHandler - - Switch to the stack specified by the sp argument - -Parameters : - POSIX signal handler parameter list ("man sigaction" for details) - sp - stack pointer of the stack to execute the handler on. - If sp == 0, execute it on the original stack where the signal has occured. -Return : - The return value from the signal handler ---*/ -static bool SwitchStackAndExecuteHandler(int code, siginfo_t *siginfo, void *context, size_t sp) -{ - // Establish a return point in case the common_signal_handler returns - - volatile bool contextInitialization = true; - - void *ptr = alloca(sizeof(SignalHandlerWorkerReturnPoint) + alignof(SignalHandlerWorkerReturnPoint) - 1); - SignalHandlerWorkerReturnPoint *pReturnPoint = (SignalHandlerWorkerReturnPoint *)ALIGN_UP(ptr, alignof(SignalHandlerWorkerReturnPoint)); - RtlCaptureContext(&pReturnPoint->context); - - // When the signal handler worker completes, it uses setcontext to return to this point - - if (contextInitialization) - { - contextInitialization = false; - ExecuteHandlerOnCustomStack(code, siginfo, context, sp, pReturnPoint); - _ASSERTE(FALSE); // The ExecuteHandlerOnCustomStack should never return - } - - return pReturnPoint->returnFromHandler; -} - /*++ Function : sigsegv_handler @@ -511,30 +453,8 @@ static void sigsegv_handler(int code, siginfo_t *siginfo, void *context) // we have a stack overflow. if ((failureAddress - (sp - GetVirtualPageSize())) < 2 * GetVirtualPageSize()) { - if (GetCurrentPalThread()) - { - size_t handlerStackTop = __sync_val_compare_and_swap((size_t*)&g_stackOverflowHandlerStack, (size_t)g_stackOverflowHandlerStack, 0); - if (handlerStackTop == 0) - { - // We have only one stack for handling stack overflow preallocated. We let only the first thread that hits stack overflow to - // run the exception handling code on that stack (which ends up just dumping the stack trace and aborting the process). - // Other threads are held spinning and sleeping here until the process exits. - while (true) - { - sleep(1); - } - } - - if (SwitchStackAndExecuteHandler(code, siginfo, context, (size_t)handlerStackTop)) - { - PROCAbort(); - } - } - else - { - (void)write(STDERR_FILENO, StackOverflowMessage, sizeof(StackOverflowMessage) - 1); - PROCAbort(); - } + (void)write(STDERR_FILENO, StackOverflowMessage, sizeof(StackOverflowMessage) - 1); + PROCAbort(); } // Now that we know the SIGSEGV didn't happen due to a stack overflow, execute the common @@ -542,7 +462,24 @@ static void sigsegv_handler(int code, siginfo_t *siginfo, void *context) if (GetCurrentPalThread() && IsRunningOnAlternateStack(context)) { - if (SwitchStackAndExecuteHandler(code, siginfo, context, 0 /* sp */)) // sp == 0 indicates execution on the original stack + // Establish a return point in case the common_signal_handler returns + + volatile bool contextInitialization = true; + + void *ptr = alloca(sizeof(SignalHandlerWorkerReturnPoint) + alignof(SignalHandlerWorkerReturnPoint) - 1); + SignalHandlerWorkerReturnPoint *pReturnPoint = (SignalHandlerWorkerReturnPoint *)ALIGN_UP(ptr, alignof(SignalHandlerWorkerReturnPoint)); + RtlCaptureContext(&pReturnPoint->context); + + // When the signal handler worker completes, it uses setcontext to return to this point + + if (contextInitialization) + { + contextInitialization = false; + ExecuteHandlerOnOriginalStack(code, siginfo, context, pReturnPoint); + _ASSERTE(FALSE); // The ExecuteHandlerOnOriginalStack should never return + } + + if (pReturnPoint->returnFromHandler) { return; } @@ -755,10 +692,7 @@ PAL_ERROR InjectActivationInternal(CorUnix::CPalThread* pThread) { #ifdef INJECT_ACTIVATION_SIGNAL int status = pthread_kill(pThread->GetPThreadSelf(), INJECT_ACTIVATION_SIGNAL); - // We can get EAGAIN when printing stack overflow stack trace and when other threads hit - // stack overflow too. Those are held in the sigsegv_handler with blocked signals until - // the process exits. - if ((status != 0) && (status != EAGAIN)) + if (status != 0) { // Failure to send the signal is fatal. There are only two cases when sending // the signal can fail. First, if the signal ID is invalid and second, diff --git a/src/coreclr/src/pal/src/include/pal/signal.hpp b/src/coreclr/src/pal/src/include/pal/signal.hpp index 7b5e1d71407b1..51b098809447a 100644 --- a/src/coreclr/src/pal/src/include/pal/signal.hpp +++ b/src/coreclr/src/pal/src/include/pal/signal.hpp @@ -78,11 +78,10 @@ extern "C" void signal_handler_worker(int code, siginfo_t *siginfo, void *contex /*++ Function : - ExecuteHandlerOnCustomStack + ExecuteHandlerOnOriginalStack - Execute signal handler on a custom stack, the current stack pointer is specified by the customSp - If the customSp is 0, then the handler is executed on the original stack where the signal was fired. - It installs a fake stack frame to enable stack unwinding to the signal source location. + Executes signal_handler_worker on the original stack where the signal occured. + It installs fake stack frame to enable stack unwinding to the signal source location. Parameters : POSIX signal handler parameter list ("man sigaction" for details) @@ -90,7 +89,7 @@ Parameters : (no return value) --*/ -void ExecuteHandlerOnCustomStack(int code, siginfo_t *siginfo, void *context, size_t sp, SignalHandlerWorkerReturnPoint* returnPoint); +void ExecuteHandlerOnOriginalStack(int code, siginfo_t *siginfo, void *context, SignalHandlerWorkerReturnPoint* returnPoint); #endif // !HAVE_MACH_EXCEPTIONS diff --git a/src/coreclr/src/pal/src/thread/thread.cpp b/src/coreclr/src/pal/src/thread/thread.cpp index 1473601c51252..c8dcc43d06f56 100644 --- a/src/coreclr/src/pal/src/thread/thread.cpp +++ b/src/coreclr/src/pal/src/thread/thread.cpp @@ -2808,7 +2808,7 @@ PAL_InjectActivation( palError = InjectActivationInternal(pTargetThread); } - if (palError != NO_ERROR) + if (palError == NO_ERROR) { pCurrentThread->SetLastError(palError); } diff --git a/src/coreclr/src/utilcode/ex.cpp b/src/coreclr/src/utilcode/ex.cpp index c970326273297..479a1e0fd08ab 100644 --- a/src/coreclr/src/utilcode/ex.cpp +++ b/src/coreclr/src/utilcode/ex.cpp @@ -1216,7 +1216,7 @@ void GenerateTopLevelHRExceptionMessage(HRESULT hresult, SString &result) #if !defined(DACCESS_COMPILE) -void GetCurrentExceptionPointers(PEXCEPTION_POINTERS pExceptionInfo DEBUG_ARG(bool checkExceptionRecordLocation)) +void GetCurrentExceptionPointers(PEXCEPTION_POINTERS pExceptionInfo) { WRAPPER_NO_CONTRACT; @@ -1227,7 +1227,7 @@ void GetCurrentExceptionPointers(PEXCEPTION_POINTERS pExceptionInfo DEBUG_ARG(bo pExceptionInfo->ExceptionRecord = pRecord; #ifdef _DEBUG - if (pRecord != NULL && checkExceptionRecordLocation) + if (pRecord != NULL) { _ASSERTE ((PVOID)(pRecord) > (PVOID)(&pRecord)); } diff --git a/src/coreclr/src/vm/amd64/JitHelpers_Fast.asm b/src/coreclr/src/vm/amd64/JitHelpers_Fast.asm index 54c0019a944c6..171e5a2c769e9 100644 --- a/src/coreclr/src/vm/amd64/JitHelpers_Fast.asm +++ b/src/coreclr/src/vm/amd64/JitHelpers_Fast.asm @@ -651,6 +651,6 @@ ProbeLoop: ret -LEAF_END_MARKED JIT_StackProbe, _TEXT +LEAF_END JIT_StackProbe, _TEXT end diff --git a/src/coreclr/src/vm/amd64/jithelpers_fast.S b/src/coreclr/src/vm/amd64/jithelpers_fast.S index d5c9eaec92377..57f7b9ed9adf7 100644 --- a/src/coreclr/src/vm/amd64/jithelpers_fast.S +++ b/src/coreclr/src/vm/amd64/jithelpers_fast.S @@ -550,7 +550,7 @@ LEAF_END JIT_Stelem_Ref__ArrayStoreCheck_Helper, _TEXT #define PAGE_SIZE 0x1000 -LEAF_ENTRY JIT_StackProbe, _TEXT +NESTED_ENTRY JIT_StackProbe, _TEXT, NoHandler // On entry: // r11 - points to the lowest address on the stack frame being allocated (i.e. [InitialSp - FrameSize]) // rsp - points to some byte on the last probed page @@ -577,4 +577,4 @@ LOCAL_LABEL(ProbeLoop): RESET_FRAME_WITH_RBP ret -LEAF_END_MARKED JIT_StackProbe, _TEXT +NESTED_END JIT_StackProbe, _TEXT diff --git a/src/coreclr/src/vm/arm/asmhelpers.S b/src/coreclr/src/vm/arm/asmhelpers.S index 34fb7235ff2f5..68e6f08a035f5 100644 --- a/src/coreclr/src/vm/arm/asmhelpers.S +++ b/src/coreclr/src/vm/arm/asmhelpers.S @@ -1466,7 +1466,7 @@ DelayLoad_Helper\suffix: #define PAGE_SIZE 0x1000 #define PAGE_SIZE_LOG2 12 - LEAF_ENTRY JIT_StackProbe, _TEXT + NESTED_ENTRY JIT_StackProbe, _TEXT, NoHandler PROLOG_PUSH "{r7}" PROLOG_STACK_SAVE r7 @@ -1484,4 +1484,4 @@ ProbeLoop: EPILOG_STACK_RESTORE r7 EPILOG_POP "{r7}" EPILOG_BRANCH_REG lr - LEAF_END_MARKED JIT_StackProbe, _TEXT + NESTED_END JIT_StackProbe, _TEXT diff --git a/src/coreclr/src/vm/arm/asmhelpers.asm b/src/coreclr/src/vm/arm/asmhelpers.asm index 89cb80f00d260..1df5420770a80 100644 --- a/src/coreclr/src/vm/arm/asmhelpers.asm +++ b/src/coreclr/src/vm/arm/asmhelpers.asm @@ -2160,7 +2160,7 @@ $__RealName ; ; NOTE: this helper will probe at least one page below the one pointed to by sp. #define PAGE_SIZE_LOG2 12 - LEAF_ENTRY JIT_StackProbe + NESTED_ENTRY JIT_StackProbe PROLOG_PUSH {r7} PROLOG_STACK_SAVE r7 @@ -2178,7 +2178,7 @@ ProbeLoop EPILOG_STACK_RESTORE r7 EPILOG_POP {r7} EPILOG_BRANCH_REG lr - LEAF_END_MARKED JIT_StackProbe + NESTED_END ; Must be at very end of file END diff --git a/src/coreclr/src/vm/eedbginterface.h b/src/coreclr/src/vm/eedbginterface.h index 2d54b5445d178..f00c4509ec829 100644 --- a/src/coreclr/src/vm/eedbginterface.h +++ b/src/coreclr/src/vm/eedbginterface.h @@ -375,7 +375,7 @@ class EEDebugInterface #endif #ifndef DACCESS_COMPILE - virtual BOOL AdjustContextForJITHelpersForDebugger(CONTEXT* context) = 0; + virtual BOOL AdjustContextForWriteBarrierForDebugger(CONTEXT* context) = 0; #endif }; diff --git a/src/coreclr/src/vm/eedbginterfaceimpl.cpp b/src/coreclr/src/vm/eedbginterfaceimpl.cpp index dc5a85c8df2f6..2c5580a0d3682 100644 --- a/src/coreclr/src/vm/eedbginterfaceimpl.cpp +++ b/src/coreclr/src/vm/eedbginterfaceimpl.cpp @@ -1584,11 +1584,11 @@ void EEDbgInterfaceImpl::ObjectRefFlush(Thread *pThread) #ifndef DACCESS_COMPILE -BOOL AdjustContextForJITHelpers(EXCEPTION_RECORD *pExceptionRecord, CONTEXT *pContext); -BOOL EEDbgInterfaceImpl::AdjustContextForJITHelpersForDebugger(CONTEXT* context) +BOOL AdjustContextForWriteBarrier(EXCEPTION_RECORD *pExceptionRecord, CONTEXT *pContext); +BOOL EEDbgInterfaceImpl::AdjustContextForWriteBarrierForDebugger(CONTEXT* context) { WRAPPER_NO_CONTRACT; - return AdjustContextForJITHelpers(nullptr, context); + return AdjustContextForWriteBarrier(nullptr, context); } #endif diff --git a/src/coreclr/src/vm/eedbginterfaceimpl.h b/src/coreclr/src/vm/eedbginterfaceimpl.h index 036aeb9ff493a..0d77f0b8fb500 100644 --- a/src/coreclr/src/vm/eedbginterfaceimpl.h +++ b/src/coreclr/src/vm/eedbginterfaceimpl.h @@ -345,7 +345,7 @@ class EEDbgInterfaceImpl : public EEDebugInterface #endif #ifndef DACCESS_COMPILE - virtual BOOL AdjustContextForJITHelpersForDebugger(CONTEXT* context); + virtual BOOL AdjustContextForWriteBarrierForDebugger(CONTEXT* context); #endif }; diff --git a/src/coreclr/src/vm/eepolicy.cpp b/src/coreclr/src/vm/eepolicy.cpp index 075737e0f8a34..e1de20a54b25c 100644 --- a/src/coreclr/src/vm/eepolicy.cpp +++ b/src/coreclr/src/vm/eepolicy.cpp @@ -700,7 +700,7 @@ void EEPolicy::HandleStackOverflow(StackOverflowDetector detector, void * pLimit } EXCEPTION_POINTERS exceptionInfo; - GetCurrentExceptionPointers(&exceptionInfo DEBUG_ARG(!pThread->IsExecutingOnAltStack())); + GetCurrentExceptionPointers(&exceptionInfo); _ASSERTE(exceptionInfo.ExceptionRecord); @@ -739,119 +739,33 @@ void EEPolicy::HandleExitProcess(ShutdownCompleteAction sca) HandleExitProcessHelper(action, 0, sca); } - -//--------------------------------------------------------------------------------------- -// This class is responsible for displaying a stack trace. It uses a condensed way for -// stack overflow stack traces where there are possibly many repeated frames. -// It displays a count and a repeated sequence of frames at the top of the stack in -// such a case, instead of displaying possibly thousands of lines with the same -// method. -//--------------------------------------------------------------------------------------- -class CallStackLogger +StackWalkAction LogCallstackForLogCallback( + CrawlFrame *pCF, // + VOID* pData // Caller's private data +) { - // MethodDescs of the stack frames, the TOS is at index 0 - CDynArray m_frames; - - // Index of a stack frame where a possible repetition of frames starts - int m_commonStartIndex = -1; - // Length of the largest found repeated sequence of frames - int m_largestCommonStartLength = 0; - // Number of repetitions of the largest repeated sequence of frames - int m_largestCommonStartRepeat = 0; - - StackWalkAction LogCallstackForLogCallbackWorker(CrawlFrame *pCF) - { - WRAPPER_NO_CONTRACT; - - MethodDesc *pMD = pCF->GetFunction(); - - if (m_commonStartIndex != -1) - { - // Some common frames were already found - - if (m_frames[m_frames.Count() - m_commonStartIndex] != pMD) - { - // The frame being added is not part of the repeated sequence - if (m_frames.Count() / m_commonStartIndex >= 2) - { - // A sequence repeated at least twice was found. It is the largest one that was found so far - m_largestCommonStartLength = m_commonStartIndex; - m_largestCommonStartRepeat = m_frames.Count() / m_commonStartIndex; - } - - m_commonStartIndex = -1; - } - } - - if (m_commonStartIndex == -1) - { - if ((m_frames.Count() != 0) && (pMD == m_frames[0])) - { - // We have found a frame with the same MethodDesc as the frame at the top of the stack, - // possibly a new repeated sequence is starting. - m_commonStartIndex = m_frames.Count(); - } - } - - MethodDesc** itemPtr = m_frames.Append(); - if (itemPtr == nullptr) - { - // Memory allocation failure - return SWA_ABORT; - } - - *itemPtr = pMD; - - return SWA_CONTINUE; - } - - void PrintFrame(int index, const WCHAR* pWordAt) + CONTRACTL { - WRAPPER_NO_CONTRACT; - - SString str(pWordAt); - - MethodDesc* pMD = m_frames[index]; - TypeString::AppendMethodInternal(str, pMD, TypeString::FormatNamespace|TypeString::FormatFullInst|TypeString::FormatSignature); - PrintToStdErrW(str.GetUnicode()); - PrintToStdErrA("\n"); + THROWS; + GC_TRIGGERS; + MODE_ANY; } + CONTRACTL_END; -public: - - // Callback called by the stack walker for each frame on the stack - static StackWalkAction LogCallstackForLogCallback(CrawlFrame *pCF, VOID* pData) - { - WRAPPER_NO_CONTRACT; + SmallStackSString *pWordAt = ((SmallStackSString*)pData); - CallStackLogger* logger = (CallStackLogger*)pData; - return logger->LogCallstackForLogCallbackWorker(pCF); - } + MethodDesc *pMD = pCF->GetFunction(); + _ASSERTE(pMD != NULL); - void PrintStackTrace(const WCHAR* pWordAt) - { - WRAPPER_NO_CONTRACT; + StackSString str; + str = *pWordAt; - if (m_largestCommonStartLength != 0) - { - SmallStackSString repeatStr; - repeatStr.AppendPrintf("Repeat %d times:\n", m_largestCommonStartRepeat); - - PrintToStdErrW(repeatStr.GetUnicode()); - PrintToStdErrA("--------------------------------\n"); - for (int i = 0; i < m_largestCommonStartLength; i++) - { - PrintFrame(i, pWordAt); - } - PrintToStdErrA("--------------------------------\n"); - } + TypeString::AppendMethodInternal(str, pMD, TypeString::FormatNamespace|TypeString::FormatFullInst|TypeString::FormatSignature); + PrintToStdErrW(str.GetUnicode()); + PrintToStdErrA("\n"); - for (int i = m_largestCommonStartLength * m_largestCommonStartRepeat; i < m_frames.Count(); i++) - { - PrintFrame(i, pWordAt); - } - } -}; + return SWA_CONTINUE; +} //--------------------------------------------------------------------------------------- // @@ -863,16 +777,14 @@ class CallStackLogger // Return Value: // None // -inline void LogCallstackForLogWorker(bool isStackOverflow = false) +inline void LogCallstackForLogWorker() { - WRAPPER_NO_CONTRACT; - Thread* pThread = GetThread(); _ASSERTE (pThread); SmallStackSString WordAt; - if (isStackOverflow || !WordAt.LoadResource(CCompRC::Optional, IDS_ER_WORDAT)) + if (!WordAt.LoadResource(CCompRC::Optional, IDS_ER_WORDAT)) { WordAt.Set(W(" at")); } @@ -882,12 +794,7 @@ inline void LogCallstackForLogWorker(bool isStackOverflow = false) } WordAt += W(" "); - CallStackLogger logger; - - pThread->StackWalkFrames(&CallStackLogger::LogCallstackForLogCallback, &logger, QUICKUNWIND | FUNCTIONSONLY); - - logger.PrintStackTrace(WordAt.GetUnicode()); - + pThread->StackWalkFrames(&LogCallstackForLogCallback, &WordAt, QUICKUNWIND | FUNCTIONSONLY); } //--------------------------------------------------------------------------------------- @@ -1149,35 +1056,7 @@ void DECLSPEC_NORETURN EEPolicy::HandleFatalStackOverflow(EXCEPTION_POINTERS *pE STRESS_LOG0(LF_EH, LL_INFO100, "In EEPolicy::HandleFatalStackOverflow\n"); - FrameWithCookie fef; -#if defined(FEATURE_EH_FUNCLETS) - *((&fef)->GetGSCookiePtr()) = GetProcessGSCookie(); -#endif // FEATURE_EH_FUNCLETS - if (pExceptionInfo && pExceptionInfo->ContextRecord) - { - GCX_COOP(); - AdjustContextForJITHelpers(pExceptionInfo->ExceptionRecord, pExceptionInfo->ContextRecord); - fef.InitAndLink(pExceptionInfo->ContextRecord); - } - - static volatile LONG g_stackOverflowCallStackLogged = 0; - - // Dump stack trace only for the first thread failing with stack overflow to prevent mixing - // multiple stack traces together. - if (InterlockedCompareExchange(&g_stackOverflowCallStackLogged, 1, 0) == 0) - { - DisplayStackOverflowException(); - LogCallstackForLogWorker(true /* isStackOverflow */); - g_stackOverflowCallStackLogged = 2; - } - else - { - // Wait for the thread that is logging the stack trace to complete - while (g_stackOverflowCallStackLogged != 2) - { - Sleep(50); - } - } + DisplayStackOverflowException(); if(ETW_EVENT_ENABLED(MICROSOFT_WINDOWS_DOTNETRUNTIME_PRIVATE_PROVIDER_DOTNET_Context, FailFast)) { @@ -1218,6 +1097,15 @@ void DECLSPEC_NORETURN EEPolicy::HandleFatalStackOverflow(EXCEPTION_POINTERS *pE fTreatAsNativeUnhandledException = TRUE; } } + FrameWithCookie fef; +#if defined(FEATURE_EH_FUNCLETS) + *((&fef)->GetGSCookiePtr()) = GetProcessGSCookie(); +#endif // FEATURE_EH_FUNCLETS + if (pExceptionInfo && pExceptionInfo->ContextRecord) + { + GCX_COOP(); + fef.InitAndLink(pExceptionInfo->ContextRecord); + } #ifndef TARGET_UNIX if (IsWatsonEnabled() && (g_pDebugInterface != NULL)) diff --git a/src/coreclr/src/vm/excep.cpp b/src/coreclr/src/vm/excep.cpp index 35a39f359cecc..3394a3fc01c4f 100644 --- a/src/coreclr/src/vm/excep.cpp +++ b/src/coreclr/src/vm/excep.cpp @@ -6638,10 +6638,6 @@ IsDebuggerFault(EXCEPTION_RECORD *pExceptionRecord, #endif // TARGET_UNIX -#ifndef TARGET_ARM64 -EXTERN_C void JIT_StackProbe_End(); -#endif // TARGET_ARM64 - #ifdef FEATURE_EH_FUNCLETS #ifndef TARGET_X86 @@ -6707,9 +6703,6 @@ bool IsIPInMarkedJitHelper(UINT_PTR uControlPc) CHECK_RANGE(JIT_WriteBarrier) CHECK_RANGE(JIT_CheckedWriteBarrier) CHECK_RANGE(JIT_ByRefWriteBarrier) -#if !defined(TARGET_ARM64) - CHECK_RANGE(JIT_StackProbe) -#endif // !TARGET_ARM64 #else #ifdef TARGET_UNIX CHECK_RANGE(JIT_WriteBarrierGroup) @@ -6727,7 +6720,7 @@ bool IsIPInMarkedJitHelper(UINT_PTR uControlPc) // Returns TRUE if caller should resume execution. BOOL -AdjustContextForJITHelpers( +AdjustContextForWriteBarrier( EXCEPTION_RECORD *pExceptionRecord, CONTEXT *pContext) { @@ -6746,7 +6739,7 @@ AdjustContextForJITHelpers( #ifdef FEATURE_DATABREAKPOINT - // If pExceptionRecord is null, it means it is called from EEDbgInterfaceImpl::AdjustContextForJITHelpersForDebugger() + // If pExceptionRecord is null, it means it is called from EEDbgInterfaceImpl::AdjustContextForWriteBarrierForDebugger() // This is called only when a data breakpoint is hitm which could be inside a JIT write barrier helper and required // this logic to help unwind out of it. For the x86, not patched case, we assume the IP lies within the region where we // have already saved the registers on the stack, and therefore the code unwind those registers as well. This is not true @@ -6799,19 +6792,6 @@ AdjustContextForJITHelpers( // put ESP back to what it was before the call. SetSP(pContext, PCODE((BYTE*)GetSP(pContext) + sizeof(void*))); } - - if ((f_IP >= (void *) JIT_StackProbe) && (f_IP <= (void *) JIT_StackProbe_End)) - { - TADDR ebp = GetFP(pContext); - void* callsite = (void *)*dac_cast(ebp + 4); - pExceptionRecord->ExceptionAddress = callsite; - SetIP(pContext, (PCODE)callsite); - - // Restore EBP / ESP back to what it was before the call. - SetFP(pContext, *dac_cast(ebp)); - SetSP(pContext, ebp + 8); - } - return FALSE; #elif defined(FEATURE_EH_FUNCLETS) // TARGET_X86 && !TARGET_UNIX void* f_IP = dac_cast(GetIP(pContext)); @@ -6880,7 +6860,7 @@ AdjustContextForJITHelpers( return FALSE; #else // FEATURE_EH_FUNCLETS - PORTABILITY_ASSERT("AdjustContextForJITHelpers"); + PORTABILITY_ASSERT("AdjustContextForWriteBarrier"); return FALSE; #endif // ELSE } @@ -7487,9 +7467,9 @@ VEH_ACTION WINAPI CLRVectoredExceptionHandlerPhase3(PEXCEPTION_POINTERS pExcepti { if (IsWellFormedAV(pExceptionRecord)) { - if (AdjustContextForJITHelpers(pExceptionRecord, pContext)) + if (AdjustContextForWriteBarrier(pExceptionRecord, pContext)) { - // On x86, AdjustContextForJITHelpers simply backs up AV's + // On x86, AdjustContextForWriteBarrier simply backs up AV's // in write barrier helpers into the calling frame, so that // the subsequent logic here sees a managed fault. // diff --git a/src/coreclr/src/vm/excep.h b/src/coreclr/src/vm/excep.h index b6fb51242dc1f..7f9aba1b30995 100644 --- a/src/coreclr/src/vm/excep.h +++ b/src/coreclr/src/vm/excep.h @@ -32,8 +32,6 @@ BOOL IsIPinVirtualStub(PCODE f_IP); #endif // VSD_STUB_CAN_THROW_AV bool IsIPInMarkedJitHelper(UINT_PTR uControlPc); -BOOL AdjustContextForJITHelpers(EXCEPTION_RECORD *pExceptionRecord, CONTEXT *pContext); - #if defined(FEATURE_HIJACK) && (!defined(TARGET_X86) || defined(TARGET_UNIX)) // General purpose functions for use on an IP in jitted code. diff --git a/src/coreclr/src/vm/exceptionhandling.cpp b/src/coreclr/src/vm/exceptionhandling.cpp index f48f36a20391b..827637b53a30a 100644 --- a/src/coreclr/src/vm/exceptionhandling.cpp +++ b/src/coreclr/src/vm/exceptionhandling.cpp @@ -5217,13 +5217,6 @@ BOOL HandleHardwareException(PAL_SEHException* ex) { _ASSERTE(IsSafeToHandleHardwareException(ex->GetContextRecord(), ex->GetExceptionRecord())); - if (ex->GetExceptionRecord()->ExceptionCode == EXCEPTION_STACK_OVERFLOW) - { - GetThread()->SetExecutingOnAltStack(); - EEPolicy::HandleFatalStackOverflow(&ex->ExceptionPointers, FALSE); - UNREACHABLE(); - } - if (ex->GetExceptionRecord()->ExceptionCode != STATUS_BREAKPOINT && ex->GetExceptionRecord()->ExceptionCode != STATUS_SINGLE_STEP) { // A hardware exception is handled only if it happened in a jitted code or @@ -5284,7 +5277,6 @@ BOOL HandleHardwareException(PAL_SEHException* ex) fef.InitAndLink(ex->GetContextRecord()); } - SaveCurrentExceptionInfo(ex->GetExceptionRecord(), ex->GetContextRecord()); DispatchManagedException(*ex, true /* isHardwareException */); UNREACHABLE(); } diff --git a/src/coreclr/src/vm/frames.cpp b/src/coreclr/src/vm/frames.cpp index 9210323fcc5ea..fafc7d3d68117 100644 --- a/src/coreclr/src/vm/frames.cpp +++ b/src/coreclr/src/vm/frames.cpp @@ -402,8 +402,7 @@ VOID Frame::Push(Thread *pThread) // in which the C compiler will lay them out in the stack frame. // So GetOsPageSize() is a guess of the maximum stack frame size of any method // with multiple Frames in mscorwks.dll - _ASSERTE(pThread->IsExecutingOnAltStack() || - ((m_Next == FRAME_TOP) || + _ASSERTE(((m_Next == FRAME_TOP) || (PBYTE(m_Next) + (2 * GetOsPageSize())) > PBYTE(this)) && "Pushing a frame out of order ?"); diff --git a/src/coreclr/src/vm/i386/jithelp.S b/src/coreclr/src/vm/i386/jithelp.S index 86a25f98d5063..49a5aa16307ed 100644 --- a/src/coreclr/src/vm/i386/jithelp.S +++ b/src/coreclr/src/vm/i386/jithelp.S @@ -27,8 +27,8 @@ // // ******************************************************************************* -// The code here is tightly coupled with AdjustContextForJITHelpers, if you change -// anything here, you might need to change AdjustContextForJITHelpers as well +// The code here is tightly coupled with AdjustContextForWriteBarrier, if you change +// anything here, you might need to change AdjustContextForWriteBarrier as well .macro WriteBarrierHelper rg .align 4 @@ -80,7 +80,7 @@ PATCH_LABEL JIT_DebugWriteBarrier\rg #ifdef WRITE_BARRIER_CHECK // Test dest here so if it is bad AV would happen before we change register/stack - // status. This makes job of AdjustContextForJITHelpers easier. + // status. This makes job of AdjustContextForWriteBarrier easier. cmp BYTE PTR [edx], 0 // ALSO update the shadow GC heap if that is enabled // Make ebp into the temporary src register. We need to do this so that we can use ecx @@ -226,8 +226,8 @@ NESTED_END JIT_CheckedWriteBarrier\rg, _TEXT // // ******************************************************************************* // -// The code here is tightly coupled with AdjustContextForJITHelpers, if you change -// anything here, you might need to change AdjustContextForJITHelpers as well +// The code here is tightly coupled with AdjustContextForWriteBarrier, if you change +// anything here, you might need to change AdjustContextForWriteBarrier as well // .macro ByRefWriteBarrierHelper .align 4 @@ -253,7 +253,7 @@ LEAF_ENTRY JIT_ByRefWriteBarrier, _TEXT #ifdef WRITE_BARRIER_CHECK // Test dest here so if it is bad AV would happen before we change register/stack - // status. This makes job of AdjustContextForJITHelpers easier. + // status. This makes job of AdjustContextForWriteBarrier easier. cmp BYTE PTR [edi], 0 // ALSO update the shadow GC heap if that is enabled diff --git a/src/coreclr/src/vm/i386/jithelp.asm b/src/coreclr/src/vm/i386/jithelp.asm index 3eec4408cfab4..14c3975523830 100644 --- a/src/coreclr/src/vm/i386/jithelp.asm +++ b/src/coreclr/src/vm/i386/jithelp.asm @@ -124,8 +124,8 @@ ENDM ; ;******************************************************************************* -; The code here is tightly coupled with AdjustContextForJITHelpers, if you change -; anything here, you might need to change AdjustContextForJITHelpers as well +; The code here is tightly coupled with AdjustContextForWriteBarrier, if you change +; anything here, you might need to change AdjustContextForWriteBarrier as well ; Note that beside the AV case, we might be unwinding inside the region where we have ; already push ecx and ebp in the branch under FEATURE_DATABREAKPOINT WriteBarrierHelper MACRO rg @@ -176,7 +176,7 @@ endif ifdef WRITE_BARRIER_CHECK ; Test dest here so if it is bad AV would happen before we change register/stack - ; status. This makes job of AdjustContextForJITHelpers easier. + ; status. This makes job of AdjustContextForWriteBarrier easier. cmp [edx], 0 ;; ALSO update the shadow GC heap if that is enabled ; Make ebp into the temporary src register. We need to do this so that we can use ecx @@ -293,8 +293,8 @@ ENDM ; ;******************************************************************************* -; The code here is tightly coupled with AdjustContextForJITHelpers, if you change -; anything here, you might need to change AdjustContextForJITHelpers as well +; The code here is tightly coupled with AdjustContextForWriteBarrier, if you change +; anything here, you might need to change AdjustContextForWriteBarrier as well ByRefWriteBarrierHelper MACRO ALIGN 4 @@ -314,7 +314,7 @@ endif ifdef WRITE_BARRIER_CHECK ; Test dest here so if it is bad AV would happen before we change register/stack - ; status. This makes job of AdjustContextForJITHelpers easier. + ; status. This makes job of AdjustContextForWriteBarrier easier. cmp [edi], 0 ;; ALSO update the shadow GC heap if that is enabled @@ -1337,8 +1337,8 @@ _JIT_StackProbe@0 PROC public and esp, -PAGE_SIZE ; esp points to the **lowest address** on the last probed page ; This is done to make the loop end condition simpler. ProbeLoop: - test [esp - 4], eax ; esp points to the lowest address on the **last probed** page sub esp, PAGE_SIZE ; esp points to the lowest address of the **next page** to probe + test [esp], eax ; esp points to the lowest address on the **last probed** page cmp esp, eax jg ProbeLoop ; if esp > eax, then we need to probe at least one more page. @@ -1348,9 +1348,4 @@ ProbeLoop: _JIT_StackProbe@0 ENDP -PUBLIC _JIT_StackProbe_End@0 -_JIT_StackProbe_End@0 PROC - ret -_JIT_StackProbe_End@0 ENDP - end diff --git a/src/coreclr/src/vm/stackwalk.cpp b/src/coreclr/src/vm/stackwalk.cpp index 66890ec1002a6..0251b05724f8c 100644 --- a/src/coreclr/src/vm/stackwalk.cpp +++ b/src/coreclr/src/vm/stackwalk.cpp @@ -2570,9 +2570,9 @@ StackWalkAction StackFrameIterator::NextRaw(void) PTR_VOID newSP = PTR_VOID((TADDR)GetRegdisplaySP(m_crawl.pRD)); #ifndef NO_FIXED_STACK_LIMIT - FAIL_IF_SPECULATIVE_WALK(m_crawl.pThread->IsExecutingOnAltStack() || newSP >= m_crawl.pThread->GetCachedStackLimit()); + FAIL_IF_SPECULATIVE_WALK(newSP >= m_crawl.pThread->GetCachedStackLimit()); #endif // !NO_FIXED_STACK_LIMIT - FAIL_IF_SPECULATIVE_WALK(m_crawl.pThread->IsExecutingOnAltStack() || newSP < m_crawl.pThread->GetCachedStackBase()); + FAIL_IF_SPECULATIVE_WALK(newSP < m_crawl.pThread->GetCachedStackBase()); #undef FAIL_IF_SPECULATIVE_WALK diff --git a/src/coreclr/src/vm/threads.cpp b/src/coreclr/src/vm/threads.cpp index f9586156b7b55..da222bc10253f 100644 --- a/src/coreclr/src/vm/threads.cpp +++ b/src/coreclr/src/vm/threads.cpp @@ -184,8 +184,8 @@ void Thread::SetFrame(Frame *pFrame) if (pFrame == stopFrame) _ASSERTE(!"SetFrame frame == stopFrame"); - _ASSERTE(IsExecutingOnAltStack() || espVal < pFrame); - _ASSERTE(IsExecutingOnAltStack() || pFrame < m_CacheStackBase); + _ASSERTE(espVal < pFrame); + _ASSERTE(pFrame < m_CacheStackBase); _ASSERTE(pFrame->GetFrameType() < Frame::TYPE_COUNT); pFrame = pFrame->m_Next; @@ -6481,7 +6481,7 @@ HRESULT Thread::CLRSetThreadStackGuarantee(SetThreadStackGuaranteeScope fScope) // -additionally, we need to provide some region to hosts to allow for lock acquisition in a hosted scenario // EXTRA_PAGES = 3; - INDEBUG(EXTRA_PAGES += 3); + INDEBUG(EXTRA_PAGES += 1); int ThreadGuardPages = CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_ThreadGuardPages); if (ThreadGuardPages == 0) @@ -6495,7 +6495,7 @@ HRESULT Thread::CLRSetThreadStackGuarantee(SetThreadStackGuaranteeScope fScope) #else // HOST_64BIT #ifdef _DEBUG - uGuardSize += (3 * GetOsPageSize()); // three extra pages for debug infrastructure + uGuardSize += (1 * GetOsPageSize()); // one extra page for debug infrastructure #endif // _DEBUG #endif // HOST_64BIT @@ -7106,9 +7106,9 @@ void CheckRegDisplaySP (REGDISPLAY *pRD) if (pRD->SP && pRD->_pThread) { #ifndef NO_FIXED_STACK_LIMIT - _ASSERTE(pRD->_pThread->IsExecutingOnAltStack() || PTR_VOID(pRD->SP) >= pRD->_pThread->GetCachedStackLimit()); + _ASSERTE(PTR_VOID(pRD->SP) >= pRD->_pThread->GetCachedStackLimit()); #endif // NO_FIXED_STACK_LIMIT - _ASSERTE(pRD->_pThread->IsExecutingOnAltStack() || PTR_VOID(pRD->SP) < pRD->_pThread->GetCachedStackBase()); + _ASSERTE(PTR_VOID(pRD->SP) < pRD->_pThread->GetCachedStackBase()); } } diff --git a/src/coreclr/src/vm/threads.h b/src/coreclr/src/vm/threads.h index 112a96d42134d..1810c3ee0d878 100644 --- a/src/coreclr/src/vm/threads.h +++ b/src/coreclr/src/vm/threads.h @@ -1035,8 +1035,6 @@ class Thread if(STSGuarantee_Force == fScope) return TRUE; - // For debug, always enable setting thread stack guarantee so that we can print the stack trace -#ifndef DEBUG //The runtime must be hosted to have escalation policy //If escalation policy is enabled but StackOverflow is not part of the policy // then we don't use SetThreadStackGuarantee @@ -1046,7 +1044,6 @@ class Thread //FAIL_StackOverflow is ProcessExit so don't use SetThreadStackGuarantee return FALSE; } -#endif // DEBUG return TRUE; } @@ -1084,7 +1081,7 @@ class Thread TS_LegalToJoin = 0x00000020, // Is it now legal to attempt a Join() - TS_ExecutingOnAltStack = 0x00000040, // Runtime is executing on an alternate stack located anywhere in the memory + // unused = 0x00000040, #ifdef FEATURE_HIJACK TS_Hijacked = 0x00000080, // Return address has been hijacked @@ -1419,18 +1416,6 @@ class Thread } #endif // DACCESS_COMPILE - DWORD IsExecutingOnAltStack() - { - LIMITED_METHOD_CONTRACT; - return (m_State & TS_ExecutingOnAltStack); - } - - void SetExecutingOnAltStack() - { - LIMITED_METHOD_CONTRACT; - FastInterlockOr((ULONG *) &m_State, TS_ExecutingOnAltStack); - } - DWORD IsBackground() { LIMITED_METHOD_CONTRACT; @@ -1856,7 +1841,7 @@ class Thread { void* curSP; curSP = (void *)GetCurrentSP(); - _ASSERTE(IsExecutingOnAltStack() || (curSP <= m_pFrame && m_pFrame < m_CacheStackBase) || m_pFrame == (Frame*) -1); + _ASSERTE((curSP <= m_pFrame && m_pFrame < m_CacheStackBase) || m_pFrame == (Frame*) -1); } #endif