summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Au <andrewau@microsoft.com>2018-10-09 17:32:33 -0700
committerAndrew Au <cshung@gmail.com>2018-11-06 18:34:47 -0800
commitb70d04f9112548b1718e1768cf0cb35943724946 (patch)
treea40cef5be3b9e2fee87b5705383bb754b51fae9d
parent2db5af268afc606a5ce4675899af5808c6b8a459 (diff)
downloadcoreclr-b70d04f9112548b1718e1768cf0cb35943724946.tar.gz
coreclr-b70d04f9112548b1718e1768cf0cb35943724946.tar.bz2
coreclr-b70d04f9112548b1718e1768cf0cb35943724946.zip
x86 only stackwalk fix
-rw-r--r--src/debug/ee/controller.cpp30
-rw-r--r--src/debug/ee/controller.h20
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)