diff options
author | Andrew Au <andrewau@microsoft.com> | 2018-10-09 17:32:33 -0700 |
---|---|---|
committer | Andrew Au <cshung@gmail.com> | 2018-11-06 18:34:47 -0800 |
commit | b70d04f9112548b1718e1768cf0cb35943724946 (patch) | |
tree | a40cef5be3b9e2fee87b5705383bb754b51fae9d | |
parent | 2db5af268afc606a5ce4675899af5808c6b8a459 (diff) | |
download | coreclr-b70d04f9112548b1718e1768cf0cb35943724946.tar.gz coreclr-b70d04f9112548b1718e1768cf0cb35943724946.tar.bz2 coreclr-b70d04f9112548b1718e1768cf0cb35943724946.zip |
x86 only stackwalk fix
-rw-r--r-- | src/debug/ee/controller.cpp | 30 | ||||
-rw-r--r-- | src/debug/ee/controller.h | 20 |
2 files changed, 39 insertions, 11 deletions
diff --git a/src/debug/ee/controller.cpp b/src/debug/ee/controller.cpp index 74d9f115cf..60d634a07d 100644 --- a/src/debug/ee/controller.cpp +++ b/src/debug/ee/controller.cpp @@ -944,6 +944,11 @@ HRESULT DebuggerController::Initialize() // //--------------------------------------------------------------------------------------- +bool DebuggerController::s_fUnwoundWriteBarrier = false; +DWORD DebuggerController::s_eipBeforeUnwoundWriteBarrier = 0; +DWORD DebuggerController::s_ecxBeforeUnwoundWriteBarrier = 0; +DWORD DebuggerController::s_ebpBeforeUnwoundWriteBarrier = 0; + DebuggerController::DebuggerController(Thread * pThread, AppDomain * pAppDomain) : m_pAppDomain(pAppDomain), m_thread(pThread), @@ -2730,6 +2735,20 @@ DPOSS_ACTION DebuggerController::ScanForTriggers(CORDB_ADDRESS_TYPE *address, tpr != TPR_TRIGGER_ONLY_THIS && DebuggerDataBreakpoint::TriggerDataBreakpoint(thread, context)) { + if (1) /* FIXME : IP range check is required */ + { + // TODO: Comment on the JIT helper as well + DWORD* esp = (DWORD*)context->Esp; + DebuggerController::s_eipBeforeUnwoundWriteBarrier = context->Eip; + DebuggerController::s_ebpBeforeUnwoundWriteBarrier = context->Ebp; + DebuggerController::s_ecxBeforeUnwoundWriteBarrier = context->Ecx; + context->Ebp = *esp; esp++; + context->Ecx = *esp; esp++; + context->Eip = *esp; esp++; + context->Esp = (DWORD)esp; + + DebuggerController::s_fUnwoundWriteBarrier = true; + } DebuggerDataBreakpoint *pDataBreakpoint = new (interopsafe) DebuggerDataBreakpoint(thread); pDcq->dcqEnqueue(pDataBreakpoint, FALSE); } @@ -3015,7 +3034,18 @@ DPOSS_ACTION DebuggerController::DispatchPatchOrSingleStep(Thread *thread, CONTE // If we need to to a re-abort (see below), then save the current IP in the thread's context before we block and // possibly let another func eval get setup. reabort = thread->m_StateNC & Thread::TSNC_DebuggerReAbort; + SENDIPCEVENT_END; + + if (DebuggerController::s_fUnwoundWriteBarrier) + { + DWORD* esp = (DWORD*)context->Esp; + context->Eip = DebuggerController::s_eipBeforeUnwoundWriteBarrier; esp--; + context->Ecx = DebuggerController::s_ecxBeforeUnwoundWriteBarrier; esp--; + context->Ebp = DebuggerController::s_ebpBeforeUnwoundWriteBarrier; esp--; + context->Esp = (DWORD)esp; + DebuggerController::s_fUnwoundWriteBarrier = false; + } if (!atSafePlace) g_pDebugger->DecThreadsAtUnsafePlaces(); diff --git a/src/debug/ee/controller.h b/src/debug/ee/controller.h index d73a432749..8cc242f8a8 100644 --- a/src/debug/ee/controller.h +++ b/src/debug/ee/controller.h @@ -1386,7 +1386,7 @@ public: // the bp. So we pass in an extra flag, fInteruptedBySetIp, to let the controller decide how to handle this. // Since SetIP only works within a single function, this can only be an issue if a thread's current stopping // location and the patch it set are in the same function. (So this could happen for step-over, but never - // setp-out). + // step-out). // This flag will almost always be false. // // Once we actually send the event, we're under the debugger lock, and so the world is stable underneath us. @@ -1414,7 +1414,13 @@ private: bool m_deleted; bool m_fEnableMethodEnter; + static bool s_fUnwoundWriteBarrier; + static DWORD s_eipBeforeUnwoundWriteBarrier; + static DWORD s_ecxBeforeUnwoundWriteBarrier; + static DWORD s_ebpBeforeUnwoundWriteBarrier; + #endif // !DACCESS_COMPILE + }; @@ -1798,16 +1804,8 @@ public: CONTEXT *context = g_pEEInterface->GetThreadFilterContext(thread); - // If we got interupted by SetIp, we just don't send the IPC event. Our triggers are still - // active so no harm done. - if (!fInteruptedBySetIp) - { - g_pDebugger->SendDataBreakpoint(thread, context, this); - return true; - } - - // Controller is still alive, will fire if we hit the breakpoint again. - return false; + g_pDebugger->SendDataBreakpoint(thread, context, this); + return true; } static bool TriggerDataBreakpoint(Thread *thread, CONTEXT * pContext) |