[Lldb-commits] [lldb] r212559 - Add the ability to provide a "count" option to the various "thread step-*" operations. Only

Jim Ingham jingham at apple.com
Tue Jul 8 12:28:57 PDT 2014


Author: jingham
Date: Tue Jul  8 14:28:57 2014
New Revision: 212559

URL: http://llvm.org/viewvc/llvm-project?rev=212559&view=rev
Log:
Add the ability to provide a "count" option to the various "thread step-*" operations.  Only
step-inst and step-inst are currently supported, the rest just warn that they are not supported
if you try to provide a count.

Modified:
    lldb/trunk/include/lldb/Target/ThreadPlan.h
    lldb/trunk/include/lldb/Target/ThreadPlanStepInstruction.h
    lldb/trunk/source/Commands/CommandObjectThread.cpp
    lldb/trunk/source/Target/ThreadPlanStepInstruction.cpp

Modified: lldb/trunk/include/lldb/Target/ThreadPlan.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/ThreadPlan.h?rev=212559&r1=212558&r2=212559&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Target/ThreadPlan.h (original)
+++ lldb/trunk/include/lldb/Target/ThreadPlan.h Tue Jul  8 14:28:57 2014
@@ -539,6 +539,27 @@ public:
         return false;
     }
     
+    virtual bool
+    SetIterationCount (size_t count)
+    {
+        if (m_takes_iteration_count)
+        {
+            // Don't tell me to do something 0 times...
+            if (count == 0)
+                return false;
+            m_iteration_count = count;
+        }
+        return m_takes_iteration_count;
+    }
+    
+    virtual size_t
+    GetIterationCount ()
+    {
+        if (!m_takes_iteration_count)
+            return 0;
+        else
+            return m_iteration_count;
+    }
 protected:
     //------------------------------------------------------------------
     // Classes that inherit from ThreadPlan can see and modify these
@@ -593,6 +614,8 @@ protected:
     Thread &m_thread;
     Vote m_stop_vote;
     Vote m_run_vote;
+    bool m_takes_iteration_count = false;
+    int32_t m_iteration_count = 1;
 
 private:
     //------------------------------------------------------------------

Modified: lldb/trunk/include/lldb/Target/ThreadPlanStepInstruction.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/ThreadPlanStepInstruction.h?rev=212559&r1=212558&r2=212559&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Target/ThreadPlanStepInstruction.h (original)
+++ lldb/trunk/include/lldb/Target/ThreadPlanStepInstruction.h Tue Jul  8 14:28:57 2014
@@ -32,6 +32,7 @@ public:
     virtual lldb::StateType GetPlanRunState ();
     virtual bool WillStop ();
     virtual bool MischiefManaged ();
+    virtual bool IsPlanStale ();
 
 protected:
     virtual bool DoPlanExplainsStop (Event *event_ptr);
@@ -41,6 +42,7 @@ protected:
                                bool stop_others,
                                Vote stop_vote,
                                Vote run_vote);
+    void SetUpState ();
 
 private:
     friend lldb::ThreadPlanSP

Modified: lldb/trunk/source/Commands/CommandObjectThread.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectThread.cpp?rev=212559&r1=212558&r2=212559&view=diff
==============================================================================
--- lldb/trunk/source/Commands/CommandObjectThread.cpp (original)
+++ lldb/trunk/source/Commands/CommandObjectThread.cpp Tue Jul  8 14:28:57 2014
@@ -371,6 +371,14 @@ public:
                 }
                 break;
             
+            case 'c':
+                {
+                    m_step_count = Args::StringToUInt32(option_arg, UINT32_MAX, 0);
+                    if (m_step_count == UINT32_MAX)
+                       error.SetErrorStringWithFormat ("invalid ignore count '%s'", option_arg);
+                    break;
+                }
+                break;
             case 'm':
                 {
                     OptionEnumValueElement *enum_values = g_option_table[option_idx].enum_values; 
@@ -408,6 +416,7 @@ public:
             m_run_mode = eOnlyDuringStepping;
             m_avoid_regexp.clear();
             m_step_in_target.clear();
+            m_step_count = 1;
         }
 
         const OptionDefinition*
@@ -426,6 +435,7 @@ public:
         RunMode m_run_mode;
         std::string m_avoid_regexp;
         std::string m_step_in_target;
+        int32_t m_step_count;
     };
 
     CommandObjectThreadStepWithTypeAndScope (CommandInterpreter &interpreter,
@@ -603,6 +613,14 @@ protected:
         {
             new_plan_sp->SetIsMasterPlan (true);
             new_plan_sp->SetOkayToDiscard (false);
+            
+            if (m_options.m_step_count > 1)
+            {
+                if (new_plan_sp->SetIterationCount(m_options.m_step_count) != m_options.m_step_count)
+                {
+                    result.AppendWarning ("step operation does not support iteration count.");
+                }
+            }
 
             process->GetThreadList().SetSelectedThreadByID (thread->GetID());
             process->Resume ();
@@ -664,6 +682,7 @@ CommandObjectThreadStepWithTypeAndScope:
 {
 { LLDB_OPT_SET_1, false, "step-in-avoids-no-debug",   'a', OptionParser::eRequiredArgument, NULL,               0, eArgTypeBoolean,     "A boolean value that sets whether stepping into functions will step over functions with no debug information."},
 { LLDB_OPT_SET_1, false, "step-out-avoids-no-debug",  'A', OptionParser::eRequiredArgument, NULL,               0, eArgTypeBoolean,     "A boolean value, if true stepping out of functions will continue to step out till it hits a function with debug information."},
+{ LLDB_OPT_SET_1, false, "count",           'c', OptionParser::eRequiredArgument, NULL,               1, eArgTypeCount,     "How many times to perform the stepping operation - currently only supported for step-inst and next-inst."},
 { LLDB_OPT_SET_1, false, "run-mode",        'm', OptionParser::eRequiredArgument, g_tri_running_mode, 0, eArgTypeRunMode, "Determine how to run other threads while stepping the current thread."},
 { LLDB_OPT_SET_1, false, "step-over-regexp",'r', OptionParser::eRequiredArgument, NULL,               0, eArgTypeRegularExpression,   "A regular expression that defines function names to not to stop at when stepping in."},
 { LLDB_OPT_SET_1, false, "step-in-target",  't', OptionParser::eRequiredArgument, NULL,               0, eArgTypeFunctionName,   "The name of the directly called function step in should stop at when stepping into."},

Modified: lldb/trunk/source/Target/ThreadPlanStepInstruction.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/ThreadPlanStepInstruction.cpp?rev=212559&r1=212558&r2=212559&view=diff
==============================================================================
--- lldb/trunk/source/Target/ThreadPlanStepInstruction.cpp (original)
+++ lldb/trunk/source/Target/ThreadPlanStepInstruction.cpp Tue Jul  8 14:28:57 2014
@@ -43,21 +43,28 @@ ThreadPlanStepInstruction::ThreadPlanSte
     m_stop_other_threads (stop_other_threads),
     m_step_over (step_over)
 {
+    m_takes_iteration_count = true;
+    SetUpState();
+}
+
+ThreadPlanStepInstruction::~ThreadPlanStepInstruction ()
+{
+}
+
+void
+ThreadPlanStepInstruction::SetUpState()
+{
     m_instruction_addr = m_thread.GetRegisterContext()->GetPC(0);
-    StackFrameSP m_start_frame_sp(m_thread.GetStackFrameAtIndex(0));
-    m_stack_id = m_start_frame_sp->GetStackID();
+    StackFrameSP start_frame_sp(m_thread.GetStackFrameAtIndex(0));
+    m_stack_id = start_frame_sp->GetStackID();
     
-    m_start_has_symbol = m_start_frame_sp->GetSymbolContext(eSymbolContextSymbol).symbol != NULL;
+    m_start_has_symbol = start_frame_sp->GetSymbolContext(eSymbolContextSymbol).symbol != NULL;
     
     StackFrameSP parent_frame_sp = m_thread.GetStackFrameAtIndex(1);
     if (parent_frame_sp)
         m_parent_frame_id = parent_frame_sp->GetStackID();
 }
 
-ThreadPlanStepInstruction::~ThreadPlanStepInstruction ()
-{
-}
-
 void
 ThreadPlanStepInstruction::GetDescription (Stream *s, lldb::DescriptionLevel level)
 {
@@ -106,6 +113,37 @@ ThreadPlanStepInstruction::DoPlanExplain
 }
 
 bool
+ThreadPlanStepInstruction::IsPlanStale ()
+{
+    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
+    StackID cur_frame_id = m_thread.GetStackFrameAtIndex(0)->GetStackID();
+    if (cur_frame_id == m_stack_id)
+    {
+        if (m_thread.GetRegisterContext()->GetPC(0) != m_instruction_addr)
+            return true;
+        else
+            return false;
+    }
+    else if (cur_frame_id < m_stack_id)
+    {
+        // If the current frame is younger than the start frame and we are stepping over, then we need to continue,
+        // but if we are doing just one step, we're done.
+        if (m_step_over)
+            return false;
+        else
+            return true;
+    }
+    else
+    {
+        if (log)
+        {
+            log->Printf ("ThreadPlanStepInstruction::IsPlanStale - Current frame is older than start frame, plan is stale.");
+        }
+        return true;
+    }
+}
+
+bool
 ThreadPlanStepInstruction::ShouldStop (Event *event_ptr)
 {
     if (m_step_over)
@@ -118,8 +156,18 @@ ThreadPlanStepInstruction::ShouldStop (E
         {
             if (m_thread.GetRegisterContext()->GetPC(0) != m_instruction_addr)
             {
-                SetPlanComplete();
-                return true;
+                if (--m_iteration_count <= 0)
+                {
+                    SetPlanComplete();
+                    return true;
+                }
+                else
+                {
+                    // We are still stepping, reset the start pc, and in case we've stepped out,
+                    // reset the current stack id.
+                    SetUpState();
+                    return false;
+                }
             }
             else
                 return false;
@@ -182,8 +230,18 @@ ThreadPlanStepInstruction::ShouldStop (E
     {
         if (m_thread.GetRegisterContext()->GetPC(0) != m_instruction_addr)
         {
-            SetPlanComplete();
-            return true;
+            if (--m_iteration_count <= 0)
+            {
+                SetPlanComplete();
+                return true;
+            }
+            else
+            {
+                // We are still stepping, reset the start pc, and in case we've stepped in or out,
+                // reset the current stack id.
+                SetUpState();
+                return false;
+            }
         }
         else
             return false;





More information about the lldb-commits mailing list