[Lldb-commits] [lldb] b0186c2 - [lldb] Refine ThreadPlan::ShouldAutoContinue

Dave Lee via lldb-commits lldb-commits at lists.llvm.org
Sat Feb 20 17:25:39 PST 2021


Author: Dave Lee
Date: 2021-02-20T17:25:31-08:00
New Revision: b0186c25c62e79869d37b81ad819c67a3e97b0cd

URL: https://github.com/llvm/llvm-project/commit/b0186c25c62e79869d37b81ad819c67a3e97b0cd
DIFF: https://github.com/llvm/llvm-project/commit/b0186c25c62e79869d37b81ad819c67a3e97b0cd.diff

LOG: [lldb] Refine ThreadPlan::ShouldAutoContinue

Adjust `ShouldAutoContinue` to be available to any thread plan previous to the plan that
explains a stop, not limited to the parent to the plan that explains the stop.

Before this change, `Thread::ShouldStop` did the following:

1. find the plan that explains the stop
2. if it's not a master plan, continue processing previous (aka parent) plans
3. first, call `ShouldAutoContinue` on the immediate parent of the explaining plan
4. then loop over previous plans, calling `ShouldStop` and `MischiefManaged`

Of note, the iteration in step 4 does not call `ShouldAutoContinue`, so again only the
plan just prior to the explaining plan is given the opportunity to override whether to
continue or stop.

This commit changes the loop call `ShouldAutoContinue`, giving each plan the opportunity
to override `ShouldStop` of previous plans.

Why? This allows a plan to do the following:

1. mark itself done and be popped off the stack
2. allow parent plans to finish their work, and to also be popped off the stack
3. and finally, have the thread continue, not stop

This is useful for stepping into async functions. A plan will would step far enough
enough to set a breakpoint on the async target, and then use `ShouldAutoContinue` to
unwind the necessary stepping, and then have the calling thread continue.

Differential Revision: https://reviews.llvm.org/D97076

Added: 
    

Modified: 
    lldb/include/lldb/Target/ThreadPlan.h
    lldb/source/Target/Thread.cpp

Removed: 
    


################################################################################
diff  --git a/lldb/include/lldb/Target/ThreadPlan.h b/lldb/include/lldb/Target/ThreadPlan.h
index 30e81f6e3050..007e56d4babe 100644
--- a/lldb/include/lldb/Target/ThreadPlan.h
+++ b/lldb/include/lldb/Target/ThreadPlan.h
@@ -361,6 +361,12 @@ class ThreadPlan : public std::enable_shared_from_this<ThreadPlan>,
 
   virtual bool ShouldStop(Event *event_ptr) = 0;
 
+  /// Returns whether this thread plan overrides the `ShouldStop` of
+  /// subsequently processed plans.
+  ///
+  /// When processing the thread plan stack, this function gives plans the
+  /// ability to continue - even when subsequent plans return true from
+  /// `ShouldStop`. \see Thread::ShouldStop
   virtual bool ShouldAutoContinue(Event *event_ptr) { return false; }
 
   // Whether a "stop class" event should be reported to the "outside world".

diff  --git a/lldb/source/Target/Thread.cpp b/lldb/source/Target/Thread.cpp
index 6670caa54392..854f7e81153e 100644
--- a/lldb/source/Target/Thread.cpp
+++ b/lldb/source/Target/Thread.cpp
@@ -829,6 +829,8 @@ bool Thread::ShouldStop(Event *event_ptr) {
       ThreadPlan *plan_ptr = current_plan;
       while ((plan_ptr = GetPreviousPlan(plan_ptr)) != nullptr) {
         if (plan_ptr->PlanExplainsStop(event_ptr)) {
+          LLDB_LOGF(log, "Plan %s explains stop.", plan_ptr->GetName());
+
           should_stop = plan_ptr->ShouldStop(event_ptr);
 
           // plan_ptr explains the stop, next check whether plan_ptr is done,
@@ -860,10 +862,7 @@ bool Thread::ShouldStop(Event *event_ptr) {
   }
 
   if (!done_processing_current_plan) {
-    bool over_ride_stop = current_plan->ShouldAutoContinue(event_ptr);
-
-    LLDB_LOGF(log, "Plan %s explains stop, auto-continue %i.",
-              current_plan->GetName(), over_ride_stop);
+    bool override_stop = false;
 
     // We're starting from the base plan, so just let it decide;
     if (current_plan->IsBasePlan()) {
@@ -884,20 +883,24 @@ bool Thread::ShouldStop(Event *event_ptr) {
           if (should_stop)
             current_plan->WillStop();
 
-          // If a Master Plan wants to stop, and wants to stick on the stack,
-          // we let it. Otherwise, see if the plan's parent wants to stop.
+          if (current_plan->ShouldAutoContinue(event_ptr)) {
+            override_stop = true;
+            LLDB_LOGF(log, "Plan %s auto-continue: true.",
+                      current_plan->GetName());
+          }
+
+          // If a Master Plan wants to stop, we let it. Otherwise, see if the
+          // plan's parent wants to stop.
 
+          PopPlan();
           if (should_stop && current_plan->IsMasterPlan() &&
               !current_plan->OkayToDiscard()) {
-            PopPlan();
             break;
-          } else {
-            PopPlan();
+          }
 
-            current_plan = GetCurrentPlan();
-            if (current_plan == nullptr) {
-              break;
-            }
+          current_plan = GetCurrentPlan();
+          if (current_plan == nullptr) {
+            break;
           }
         } else {
           break;
@@ -905,7 +908,7 @@ bool Thread::ShouldStop(Event *event_ptr) {
       }
     }
 
-    if (over_ride_stop)
+    if (override_stop)
       should_stop = false;
   }
 


        


More information about the lldb-commits mailing list