Single stepping out of the unsafe places (#21135)
authorAndrew Au <cshung@gmail.com>
Thu, 22 Nov 2018 00:17:06 +0000 (16:17 -0800)
committerGitHub <noreply@github.com>
Thu, 22 Nov 2018 00:17:06 +0000 (16:17 -0800)
src/debug/ee/controller.cpp
src/debug/ee/controller.h

index 9d2c196..a0d78b4 100644 (file)
@@ -9006,22 +9006,31 @@ bool DebuggerContinuableExceptionBreakpoint::SendEvent(Thread *thread, bool fIpC
 #endif // defined(_TARGET_X86_) || defined(_TARGET_AMD64_)
     if (hitDataBp)
     {
-        CONTEXT contextToAdjust;
-        BOOL adjustedContext = FALSE;
-        memcpy(&contextToAdjust, pContext, sizeof(CONTEXT));
-        adjustedContext = g_pEEInterface->AdjustContextForWriteBarrierForDebugger(&contextToAdjust);        
-        if (adjustedContext)
-        {
-            LOG((LF_CORDB, LL_INFO10000, "D::DDBP: HIT DATA BREAKPOINT INSIDE WRITE BARRIER...\n"));
-            DebuggerDataBreakpoint *pDataBreakpoint = new (interopsafe) DebuggerDataBreakpoint(thread);
-            pDataBreakpoint->AddAndActivateNativePatchForAddress((CORDB_ADDRESS_TYPE*)GetIP(&contextToAdjust), FramePointer::MakeFramePointer(GetFP(&contextToAdjust)), true, DPT_DEFAULT_TRACE_TYPE);
-            result = false;
-        }
-        else
+        if (g_pDebugger->IsThreadAtSafePlace(thread))
         {
             LOG((LF_CORDB, LL_INFO10000, "D::DDBP: HIT DATA BREAKPOINT...\n"));
             result = true;
         }
+        else
+        {
+            CONTEXT contextToAdjust;
+            BOOL adjustedContext = FALSE;
+            memcpy(&contextToAdjust, pContext, sizeof(CONTEXT));
+            adjustedContext = g_pEEInterface->AdjustContextForWriteBarrierForDebugger(&contextToAdjust);        
+            if (adjustedContext)
+            {
+                LOG((LF_CORDB, LL_INFO10000, "D::DDBP: HIT DATA BREAKPOINT INSIDE WRITE BARRIER...\n"));
+                DebuggerDataBreakpoint *pDataBreakpoint = new (interopsafe) DebuggerDataBreakpoint(thread);
+                pDataBreakpoint->AddAndActivateNativePatchForAddress((CORDB_ADDRESS_TYPE*)GetIP(&contextToAdjust), FramePointer::MakeFramePointer(GetFP(&contextToAdjust)), true, DPT_DEFAULT_TRACE_TYPE);
+            }
+            else
+            {
+                LOG((LF_CORDB, LL_INFO10000, "D::DDBP: HIT DATA BREAKPOINT BUT STILL NEED TO ROLL ...\n"));
+                DebuggerDataBreakpoint *pDataBreakpoint = new (interopsafe) DebuggerDataBreakpoint(thread);
+                pDataBreakpoint->EnableSingleStep();
+            }
+            result = false;
+        }
     }
     else
     {
@@ -9031,6 +9040,35 @@ bool DebuggerContinuableExceptionBreakpoint::SendEvent(Thread *thread, bool fIpC
     return result;
 }
 
+TP_RESULT DebuggerDataBreakpoint::TriggerPatch(DebuggerControllerPatch *patch, Thread *thread,  TRIGGER_WHY tyWhy)
+{
+    if (g_pDebugger->IsThreadAtSafePlace(thread))
+    {
+        return TPR_TRIGGER;
+    }
+    else
+    {
+        LOG((LF_CORDB, LL_INFO10000, "D::DDBP: REACH RETURN OF JIT HELPER BUT STILL NEED TO ROLL ...\n"));
+        this->EnableSingleStep();
+        return TPR_IGNORE;
+    }
+}
+
+bool DebuggerDataBreakpoint::TriggerSingleStep(Thread *thread, const BYTE *ip)
+{
+    if (g_pDebugger->IsThreadAtSafePlace(thread))
+    {
+        LOG((LF_CORDB, LL_INFO10000, "D:DDBP: Finally safe for stopping, stop stepping\n"));
+        this->DisableSingleStep();
+        return true;
+    }
+    else
+    {
+        LOG((LF_CORDB, LL_INFO10000, "D:DDBP: Still not safe for stopping, continue stepping\n"));
+        return false;
+    }
+}
+
 #endif // FEATURE_DATABREAKPOINT
 
 #endif // !DACCESS_COMPILE
index 7643b36..7756a29 100644 (file)
@@ -1789,12 +1789,9 @@ public:
         return DEBUGGER_CONTROLLER_DATA_BREAKPOINT;
     }
 
-    virtual TP_RESULT TriggerPatch(DebuggerControllerPatch *patch,
-                              Thread *thread, 
-                              TRIGGER_WHY tyWhy)
-    {
-        return TPR_TRIGGER;
-    }
+    virtual TP_RESULT TriggerPatch(DebuggerControllerPatch *patch, Thread *thread,  TRIGGER_WHY tyWhy);
+
+    virtual bool TriggerSingleStep(Thread *thread, const BYTE *ip);
 
     bool SendEvent(Thread *thread, bool fInteruptedBySetIp)
     {