[Lldb-commits] [lldb] r156105 - in /lldb/branches/lldb-platform-work: ./ include/lldb/API/ include/lldb/Target/ lldb.xcodeproj/ source/API/ source/Commands/ source/Target/ tools/debugserver/debugserver.xcodeproj/

Johnny Chen johnny.chen at apple.com
Thu May 3 14:36:32 PDT 2012


Author: johnny
Date: Thu May  3 16:36:31 2012
New Revision: 156105

URL: http://llvm.org/viewvc/llvm-project?rev=156105&view=rev
Log:
Merge changes from ToT trunk:

svn merge -r 156088:156101 https://johnny@llvm.org/svn/llvm-project/lldb/trunk .

Modified:
    lldb/branches/lldb-platform-work/   (props changed)
    lldb/branches/lldb-platform-work/include/lldb/API/SBThread.h
    lldb/branches/lldb-platform-work/include/lldb/Target/Thread.h
    lldb/branches/lldb-platform-work/include/lldb/Target/ThreadPlan.h
    lldb/branches/lldb-platform-work/include/lldb/Target/ThreadPlanStepOut.h
    lldb/branches/lldb-platform-work/include/lldb/Target/ThreadPlanStepOverRange.h
    lldb/branches/lldb-platform-work/include/lldb/Target/ThreadPlanStepRange.h
    lldb/branches/lldb-platform-work/lldb.xcodeproj/project.pbxproj
    lldb/branches/lldb-platform-work/source/API/SBThread.cpp
    lldb/branches/lldb-platform-work/source/Commands/CommandObjectBreakpoint.cpp
    lldb/branches/lldb-platform-work/source/Commands/CommandObjectThread.cpp
    lldb/branches/lldb-platform-work/source/Target/Thread.cpp
    lldb/branches/lldb-platform-work/source/Target/ThreadPlan.cpp
    lldb/branches/lldb-platform-work/source/Target/ThreadPlanStepInstruction.cpp
    lldb/branches/lldb-platform-work/source/Target/ThreadPlanStepOut.cpp
    lldb/branches/lldb-platform-work/source/Target/ThreadPlanStepOverRange.cpp
    lldb/branches/lldb-platform-work/source/Target/ThreadPlanStepRange.cpp
    lldb/branches/lldb-platform-work/source/Target/ThreadPlanStepUntil.cpp
    lldb/branches/lldb-platform-work/tools/debugserver/debugserver.xcodeproj/project.pbxproj

Propchange: lldb/branches/lldb-platform-work/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Thu May  3 16:36:31 2012
@@ -1 +1 @@
-/lldb/trunk:154223-156088
+/lldb/trunk:154223-156101

Modified: lldb/branches/lldb-platform-work/include/lldb/API/SBThread.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/include/lldb/API/SBThread.h?rev=156105&r1=156104&r2=156105&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/include/lldb/API/SBThread.h (original)
+++ lldb/branches/lldb-platform-work/include/lldb/API/SBThread.h Thu May  3 16:36:31 2012
@@ -172,6 +172,11 @@
     void
     SetThread (const lldb::ThreadSP& lldb_object_sp);
 
+#ifndef SWIG
+    SBError
+    ResumeNewPlan (lldb_private::ExecutionContext &exe_ctx, lldb_private::ThreadPlan *new_plan);
+#endif
+
 private:
     lldb::ExecutionContextRefSP m_opaque_sp;
 };

Modified: lldb/branches/lldb-platform-work/include/lldb/Target/Thread.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/include/lldb/Target/Thread.h?rev=156105&r1=156104&r2=156105&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/include/lldb/Target/Thread.h (original)
+++ lldb/branches/lldb-platform-work/include/lldb/Target/Thread.h Thu May  3 16:36:31 2012
@@ -674,6 +674,9 @@
     void
     DiscardThreadPlansUpToPlan (lldb::ThreadPlanSP &up_to_plan_sp);
 
+    void
+    DiscardThreadPlansUpToPlan (ThreadPlan *up_to_plan_ptr);
+    
     //------------------------------------------------------------------
     /// Prints the current plan stack.
     ///

Modified: lldb/branches/lldb-platform-work/include/lldb/Target/ThreadPlan.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/include/lldb/Target/ThreadPlan.h?rev=156105&r1=156104&r2=156105&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/include/lldb/Target/ThreadPlan.h (original)
+++ lldb/branches/lldb-platform-work/include/lldb/Target/ThreadPlan.h Thu May  3 16:36:31 2012
@@ -115,12 +115,33 @@
 //  figure out what to do about the plans below it in the stack.  If the stop is recoverable, then the plan that
 //  understands it can just do what it needs to set up to restart, and then continue.
 //  Otherwise, the plan that understood the stop should call DiscardPlanStack to clean up the stack below it.
-//  In the normal case, this will just collapse the plan stack up to the point of the plan that understood
+//
+//  Master plans:
+//
+//  In the normal case, when we decide to stop, we will  collapse the plan stack up to the point of the plan that understood
 //  the stop reason.  However, if a plan wishes to stay on the stack after an event it didn't directly handle
 //  it can designate itself a "Master" plan by responding true to IsMasterPlan, and then if it wants not to be
 //  discarded, it can return true to OkayToDiscard, and it and all its dependent plans will be preserved when
 //  we resume execution.
 //
+//  The other effect of being a master plan is that when the Master plan is done , if it has set "OkayToDiscard" to false,
+//  then it will be popped & execution will stop and return to the user.  Remember that if OkayToDiscard is false, the
+//  plan will be popped and control will be given to the next plan above it on the stack  So setting OkayToDiscard to
+//  false means the user will regain control when the MasterPlan is completed.
+//
+//  Between these two controls this allows things like: a MasterPlan/DontDiscard Step Over to hit a breakpoint, stop and
+//  return control to the user, but then when the user continues, the step out succeeds.
+//  Even more tricky, when the breakpoint is hit, the user can continue to step in/step over/etc, and finally when they
+//  continue, they will finish up the Step Over.
+//
+//  FIXME: MasterPlan & OkayToDiscard aren't really orthogonal.  MasterPlan designation means that this plan controls
+//  it's fate and the fate of plans below it.  OkayToDiscard tells whether the MasterPlan wants to stay on the stack.  I
+//  originally thought "MasterPlan-ness" would need to be a fixed characteristic of a ThreadPlan, in which case you needed
+//  the extra control.  But that doesn't seem to be true.  So we should be able to convert to only MasterPlan status to mean
+//  the current "MasterPlan/DontDiscard".  Then no plans would be MasterPlans by default, and you would set the ones you
+//  wanted to be "user level" in this way.
+//
+//
 //  Actually Stopping:
 //
 //  If a plan says responds "true" to ShouldStop, then it is asked if it's job is complete by calling
@@ -152,6 +173,18 @@
 //  because of a crash or breakpoint hit, it wants to unship itself, because it isn't so useful to have step in keep going
 //  after a breakpoint hit.  But it can't be the reason for the stop or no-one would see that they had hit a breakpoint.
 //
+//  Cleaning up the plan stack:
+//
+//  One of the complications of MasterPlans is that you may get past the limits of a plan without triggering it to clean
+//  itself up.  For instance, if you are doing a MasterPlan StepOver, and hit a breakpoint in a called function, then
+//  step over enough times to step out of the initial StepOver range, each of the step overs will explain the stop & 
+//  take themselves off the stack, but control would never be returned to the original StepOver.  Eventually, the user 
+//  will continue, and when that continue stops, the old stale StepOver plan that was left on the stack will get woken 
+//  up and notice it is done. But that can leave junk on the stack for a while.  To avoid that, the plans implement a
+//  "IsPlanStale" method, that can check whether it is relevant anymore.  On stop, after the regular plan negotiation, 
+//  the remaining plan stack is consulted and if any plan says it is stale, it and the plans below it are discarded from
+//  the stack.
+//
 //  Automatically Resuming:
 //
 //  If ShouldStop for all threads returns "false", then the target process will resume.  This then cycles back to
@@ -408,6 +441,12 @@
     void
     SetPlanComplete (bool success = true);
     
+    virtual bool
+    IsPlanStale ()
+    {
+        return false;
+    }
+    
     bool
     PlanSucceeded ()
     {

Modified: lldb/branches/lldb-platform-work/include/lldb/Target/ThreadPlanStepOut.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/include/lldb/Target/ThreadPlanStepOut.h?rev=156105&r1=156104&r2=156105&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/include/lldb/Target/ThreadPlanStepOut.h (original)
+++ lldb/branches/lldb-platform-work/include/lldb/Target/ThreadPlanStepOut.h Thu May  3 16:36:31 2012
@@ -42,6 +42,7 @@
     virtual bool WillStop ();
     virtual bool MischiefManaged ();
     virtual void DidPush();
+    virtual bool IsPlanStale();
     
     virtual lldb::ValueObjectSP GetReturnValueObject()
     {

Modified: lldb/branches/lldb-platform-work/include/lldb/Target/ThreadPlanStepOverRange.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/include/lldb/Target/ThreadPlanStepOverRange.h?rev=156105&r1=156104&r2=156105&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/include/lldb/Target/ThreadPlanStepOverRange.h (original)
+++ lldb/branches/lldb-platform-work/include/lldb/Target/ThreadPlanStepOverRange.h Thu May  3 16:36:31 2012
@@ -28,8 +28,7 @@
     ThreadPlanStepOverRange (Thread &thread, 
                              const AddressRange &range, 
                              const SymbolContext &addr_context, 
-                             lldb::RunMode stop_others, 
-                             bool okay_to_discard = false);
+                             lldb::RunMode stop_others);
                              
     virtual ~ThreadPlanStepOverRange ();
 

Modified: lldb/branches/lldb-platform-work/include/lldb/Target/ThreadPlanStepRange.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/include/lldb/Target/ThreadPlanStepRange.h?rev=156105&r1=156104&r2=156105&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/include/lldb/Target/ThreadPlanStepRange.h (original)
+++ lldb/branches/lldb-platform-work/include/lldb/Target/ThreadPlanStepRange.h Thu May  3 16:36:31 2012
@@ -43,6 +43,7 @@
     virtual bool WillStop ();
     virtual bool MischiefManaged ();
     virtual void DidPush ();
+    virtual bool IsPlanStale ();
 
 
     void AddRange(const AddressRange &new_range);

Modified: lldb/branches/lldb-platform-work/lldb.xcodeproj/project.pbxproj
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/lldb.xcodeproj/project.pbxproj?rev=156105&r1=156104&r2=156105&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/lldb.xcodeproj/project.pbxproj (original)
+++ lldb/branches/lldb-platform-work/lldb.xcodeproj/project.pbxproj Thu May  3 16:36:31 2012
@@ -4119,10 +4119,7 @@
 				ALWAYS_SEARCH_USER_PATHS = NO;
 				ARCHS = "$(NATIVE_ARCH)";
 				"ARCHS[sdk=iphoneos*]" = armv7;
-				"ARCHS[sdk=macosx*]" = (
-					x86_64,
-					i386,
-				);
+				"ARCHS[sdk=macosx*]" = "$(ARCHS_STANDARD_64_BIT)";
 				COPY_PHASE_STRIP = NO;
 				DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
 				GCC_C_LANGUAGE_STANDARD = gnu99;

Modified: lldb/branches/lldb-platform-work/source/API/SBThread.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/API/SBThread.cpp?rev=156105&r1=156104&r2=156105&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/API/SBThread.cpp (original)
+++ lldb/branches/lldb-platform-work/source/API/SBThread.cpp Thu May  3 16:36:31 2012
@@ -474,6 +474,47 @@
     return name;
 }
 
+SBError
+SBThread::ResumeNewPlan (ExecutionContext &exe_ctx, ThreadPlan *new_plan)
+{
+    SBError sb_error;
+    
+    Process *process = exe_ctx.GetProcessPtr();
+    if (!process)
+    {
+        sb_error.SetErrorString("No process in SBThread::ResumeNewPlan");
+        return sb_error;
+    }
+
+    Thread *thread = exe_ctx.GetThreadPtr();
+    if (!thread)
+    {
+        sb_error.SetErrorString("No thread in SBThread::ResumeNewPlan");
+        return sb_error;
+    }
+    
+    // User level plans should be Master Plans so they can be interrupted, other plans executed, and
+    // then a "continue" will resume the plan.
+    if (new_plan != NULL)
+    {
+        new_plan->SetIsMasterPlan(true);
+        new_plan->SetOkayToDiscard(false);
+    }
+    
+    // Why do we need to set the current thread by ID here???
+    process->GetThreadList().SetSelectedThreadByID (thread->GetID());
+    sb_error.ref() = process->Resume();
+    
+    if (sb_error.Success())
+    {
+        // If we are doing synchronous mode, then wait for the
+        // process to stop yet again!
+        if (process->GetTarget().GetDebugger().GetAsyncExecution () == false)
+            process->WaitForProcessToStop (NULL);
+    }
+    
+    return sb_error;
+}
 
 void
 SBThread::StepOver (lldb::RunMode stop_other_threads)
@@ -492,39 +533,31 @@
         Thread *thread = exe_ctx.GetThreadPtr();
         bool abort_other_plans = true;
         StackFrameSP frame_sp(thread->GetStackFrameAtIndex (0));
+        ThreadPlan *new_plan = NULL;
 
         if (frame_sp)
         {
             if (frame_sp->HasDebugInformation ())
             {
                 SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything));
-                thread->QueueThreadPlanForStepRange (abort_other_plans, 
-                                                     eStepTypeOver,
-                                                     sc.line_entry.range, 
-                                                     sc,
-                                                     stop_other_threads,
-                                                     false);
+                new_plan = thread->QueueThreadPlanForStepRange (abort_other_plans,
+                                                                eStepTypeOver,
+                                                                sc.line_entry.range,
+                                                                sc,
+                                                                stop_other_threads,
+                                                                false);
                 
             }
             else
             {
-                thread->QueueThreadPlanForStepSingleInstruction (true, 
-                                                                 abort_other_plans, 
-                                                                 stop_other_threads);
+                new_plan = thread->QueueThreadPlanForStepSingleInstruction (true,
+                                                                            abort_other_plans, 
+                                                                            stop_other_threads);
             }
         }
 
-        Process *process = exe_ctx.GetProcessPtr();
-        // Why do we need to set the current thread by ID here???
-        process->GetThreadList().SetSelectedThreadByID (thread->GetID());
-        Error error (process->Resume());
-        if (error.Success())
-        {
-            // If we are doing synchronous mode, then wait for the
-            // process to stop yet again!
-            if (process->GetTarget().GetDebugger().GetAsyncExecution () == false)
-                process->WaitForProcessToStop (NULL);
-        }
+        // This returns an error, we should use it!
+        ResumeNewPlan (exe_ctx, new_plan);
     }
 }
 
@@ -545,36 +578,28 @@
 
         Thread *thread = exe_ctx.GetThreadPtr();
         StackFrameSP frame_sp(thread->GetStackFrameAtIndex (0));
+        ThreadPlan *new_plan = NULL;
 
         if (frame_sp && frame_sp->HasDebugInformation ())
         {
             bool avoid_code_without_debug_info = true;
             SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything));
-            thread->QueueThreadPlanForStepRange (abort_other_plans, 
-                                                 eStepTypeInto, 
-                                                 sc.line_entry.range, 
-                                                 sc, 
-                                                 stop_other_threads,
-                                                 avoid_code_without_debug_info);
+            new_plan = thread->QueueThreadPlanForStepRange (abort_other_plans,
+                                                            eStepTypeInto,
+                                                            sc.line_entry.range,
+                                                            sc,
+                                                            stop_other_threads,
+                                                            avoid_code_without_debug_info);
         }
         else
         {
-            thread->QueueThreadPlanForStepSingleInstruction (false, 
-                                                             abort_other_plans, 
-                                                             stop_other_threads);
-        }
-
-        Process *process = exe_ctx.GetProcessPtr();
-        // Why do we need to set the current thread by ID here???
-        process->GetThreadList().SetSelectedThreadByID (thread->GetID());
-        Error error (process->Resume());
-        if (error.Success())
-        {
-            // If we are doing synchronous mode, then wait for the
-            // process to stop yet again!
-            if (process->GetTarget().GetDebugger().GetAsyncExecution () == false)
-                process->WaitForProcessToStop (NULL);
+            new_plan = thread->QueueThreadPlanForStepSingleInstruction (false,
+                                                                        abort_other_plans, 
+                                                                        stop_other_threads);
         }
+        
+        // This returns an error, we should use it!
+        ResumeNewPlan (exe_ctx, new_plan);
     }
 }
 
@@ -596,24 +621,16 @@
 
         Thread *thread = exe_ctx.GetThreadPtr();
 
-        thread->QueueThreadPlanForStepOut (abort_other_plans, 
-                                              NULL, 
-                                              false, 
-                                              stop_other_threads, 
-                                              eVoteYes, 
-                                              eVoteNoOpinion,
-                                              0);
-        
-        Process *process = exe_ctx.GetProcessPtr();
-        process->GetThreadList().SetSelectedThreadByID (thread->GetID());
-        Error error (process->Resume());
-        if (error.Success())
-        {
-            // If we are doing synchronous mode, then wait for the
-            // process to stop yet again!
-            if (process->GetTarget().GetDebugger().GetAsyncExecution () == false)
-                process->WaitForProcessToStop (NULL);
-        }
+        ThreadPlan *new_plan = thread->QueueThreadPlanForStepOut (abort_other_plans,
+                                                                  NULL, 
+                                                                  false, 
+                                                                  stop_other_threads, 
+                                                                  eVoteYes, 
+                                                                  eVoteNoOpinion,
+                                                                  0);
+                                                                  
+        // This returns an error, we should use it!
+        ResumeNewPlan (exe_ctx, new_plan);
     }
 }
 
@@ -638,24 +655,16 @@
         bool stop_other_threads = true;
         Thread *thread = exe_ctx.GetThreadPtr();
 
-        thread->QueueThreadPlanForStepOut (abort_other_plans, 
-                                              NULL, 
-                                              false, 
-                                              stop_other_threads, 
-                                              eVoteYes, 
-                                              eVoteNoOpinion,
-                                              frame_sp->GetFrameIndex());
-        
-        Process *process = exe_ctx.GetProcessPtr();
-        process->GetThreadList().SetSelectedThreadByID (thread->GetID());
-        Error error (process->Resume());
-        if (error.Success())
-        {
-            // If we are doing synchronous mode, then wait for the
-            // process to stop yet again!
-            if (process->GetTarget().GetDebugger().GetAsyncExecution () == false)
-                process->WaitForProcessToStop (NULL);
-        }
+        ThreadPlan *new_plan = thread->QueueThreadPlanForStepOut (abort_other_plans,
+                                                                    NULL, 
+                                                                    false, 
+                                                                    stop_other_threads, 
+                                                                    eVoteYes, 
+                                                                    eVoteNoOpinion,
+                                                                    frame_sp->GetFrameIndex());
+                                                                    
+        // This returns an error, we should use it!
+        ResumeNewPlan (exe_ctx, new_plan);
     }
 }
 
@@ -674,17 +683,10 @@
     {
         Mutex::Locker api_locker (exe_ctx.GetTargetPtr()->GetAPIMutex());
         Thread *thread = exe_ctx.GetThreadPtr();
-        Process *process = exe_ctx.GetProcessPtr();
-        thread->QueueThreadPlanForStepSingleInstruction (step_over, true, true);
-        process->GetThreadList().SetSelectedThreadByID (thread->GetID());
-        Error error (process->Resume());
-        if (error.Success())
-        {
-            // If we are doing synchronous mode, then wait for the
-            // process to stop yet again!
-            if (process->GetTarget().GetDebugger().GetAsyncExecution () == false)
-                process->WaitForProcessToStop (NULL);
-        }
+        ThreadPlan *new_plan = thread->QueueThreadPlanForStepSingleInstruction (step_over, true, true);
+        
+        // This returns an error, we should use it!
+        ResumeNewPlan (exe_ctx, new_plan);
     }
 }
 
@@ -707,18 +709,11 @@
         Address target_addr (addr);
 
         Thread *thread = exe_ctx.GetThreadPtr();
-        Process *process = exe_ctx.GetProcessPtr();
 
-        thread->QueueThreadPlanForRunToAddress (abort_other_plans, target_addr, stop_other_threads);
-        process->GetThreadList().SetSelectedThreadByID (thread->GetID());
-        Error error (process->Resume());
-        if (error.Success())
-        {
-            // If we are doing synchronous mode, then wait for the
-            // process to stop yet again!
-            if (process->GetTarget().GetDebugger().GetAsyncExecution () == false)
-                process->WaitForProcessToStop (NULL);
-        }
+        ThreadPlan *new_plan = thread->QueueThreadPlanForRunToAddress (abort_other_plans, target_addr, stop_other_threads);
+        
+        // This returns an error, we should use it!
+        ResumeNewPlan (exe_ctx, new_plan);
     }
 }
 
@@ -854,23 +849,13 @@
         }
         else
         {
-            thread->QueueThreadPlanForStepUntil (abort_other_plans, 
-                                                 &step_over_until_addrs[0],
-                                                 step_over_until_addrs.size(),
-                                                 stop_other_threads,
-                                                 frame_sp->GetFrameIndex());      
-
-            Process *process = exe_ctx.GetProcessPtr();
-
-            process->GetThreadList().SetSelectedThreadByID (thread->GetID());
-            sb_error.ref() = process->Resume();
-            if (sb_error->Success())
-            {
-                // If we are doing synchronous mode, then wait for the
-                // process to stop yet again!
-                if (process->GetTarget().GetDebugger().GetAsyncExecution () == false)
-                    process->WaitForProcessToStop (NULL);
-            }
+            ThreadPlan *new_plan = thread->QueueThreadPlanForStepUntil (abort_other_plans,
+                                                                        &step_over_until_addrs[0],
+                                                                        step_over_until_addrs.size(),
+                                                                        stop_other_threads,
+                                                                        frame_sp->GetFrameIndex());      
+
+            sb_error = ResumeNewPlan (exe_ctx, new_plan);
         }
     }
     else

Modified: lldb/branches/lldb-platform-work/source/Commands/CommandObjectBreakpoint.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Commands/CommandObjectBreakpoint.cpp?rev=156105&r1=156104&r2=156105&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Commands/CommandObjectBreakpoint.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Commands/CommandObjectBreakpoint.cpp Thu May  3 16:36:31 2012
@@ -81,7 +81,8 @@
 CommandObjectBreakpointSet::CommandOptions::g_option_table[] =
 {
     { LLDB_OPT_NOT_10, false, "shlib", 's', required_argument, NULL, CommandCompletions::eModuleCompletion, eArgTypeShlibName,
-        "Set the breakpoint only in this shared library (can use this option multiple times for multiple shlibs)."},
+        "Set the breakpoint only in this shared library.  "
+        "Can repeat this option multiple times to specify multiple shared libraries."},
 
     { LLDB_OPT_SET_ALL, false, "ignore-count", 'i', required_argument,   NULL, 0, eArgTypeCount,
         "Set the number of times this breakpoint is skipped before stopping." },
@@ -113,23 +114,25 @@
         "Set the breakpoint by address, at the specified address."},
 
     { LLDB_OPT_SET_3, true, "name", 'n', required_argument, NULL, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName,
-        "Set the breakpoint by function name." },
+        "Set the breakpoint by function name.  Can be repeated multiple times to make one breakpoint for multiple snames" },
 
     { LLDB_OPT_SET_4, true, "fullname", 'F', required_argument, NULL, CommandCompletions::eSymbolCompletion, eArgTypeFullName,
-        "Set the breakpoint by fully qualified function names. For C++ this means namespaces and all arguemnts, and "
-        "for Objective C this means a full function prototype with class and selector." },
+        "Set the breakpoint by fully qualified function names. For C++ this means namespaces and all arguments, and "
+        "for Objective C this means a full function prototype with class and selector.   "
+        "Can be repeated multiple times to make one breakpoint for multiple names." },
 
     { LLDB_OPT_SET_5, true, "selector", 'S', required_argument, NULL, 0, eArgTypeSelector,
-        "Set the breakpoint by ObjC selector name." },
+        "Set the breakpoint by ObjC selector name. Can be repeated multiple times to make one breakpoint for multiple Selectors." },
 
     { LLDB_OPT_SET_6, true, "method", 'M', required_argument, NULL, 0, eArgTypeMethod,
-        "Set the breakpoint by C++ method names." },
+        "Set the breakpoint by C++ method names.  Can be repeated multiple times to make one breakpoint for multiple methods." },
 
     { LLDB_OPT_SET_7, true, "func-regex", 'r', required_argument, NULL, 0, eArgTypeRegularExpression,
         "Set the breakpoint by function name, evaluating a regular-expression to find the function name(s)." },
 
     { LLDB_OPT_SET_8, true, "basename", 'b', required_argument, NULL, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName,
-        "Set the breakpoint by function basename (C++ namespaces and arguments will be ignored)." },
+        "Set the breakpoint by function basename (C++ namespaces and arguments will be ignored). "
+        "Can be repeated multiple times to make one breakpoint for multiple symbols." },
 
     { LLDB_OPT_SET_9, true, "source-pattern-regexp", 'p', required_argument, NULL, 0, eArgTypeRegularExpression,
         "Set the breakpoint specifying a regular expression to match a pattern in the source text in a given source file." },

Modified: lldb/branches/lldb-platform-work/source/Commands/CommandObjectThread.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Commands/CommandObjectThread.cpp?rev=156105&r1=156104&r2=156105&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Commands/CommandObjectThread.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Commands/CommandObjectThread.cpp Thu May  3 16:36:31 2012
@@ -451,10 +451,11 @@
             else
                 bool_stop_other_threads = true;
 
+            ThreadPlan *new_plan = NULL;
+            
             if (m_step_type == eStepTypeInto)
             {
                 StackFrame *frame = thread->GetStackFrameAtIndex(0).get();
-                ThreadPlan *new_plan;
 
                 if (frame->HasDebugInformation ())
                 {
@@ -471,14 +472,11 @@
                 }
                 else
                     new_plan = thread->QueueThreadPlanForStepSingleInstruction (false, abort_other_plans, bool_stop_other_threads);
-
-                process->GetThreadList().SetSelectedThreadByID (thread->GetID());
-                process->Resume ();
+                    
             }
             else if (m_step_type == eStepTypeOver)
             {
                 StackFrame *frame = thread->GetStackFrameAtIndex(0).get();
-                ThreadPlan *new_plan;
 
                 if (frame->HasDebugInformation())
                     new_plan = thread->QueueThreadPlanForStepRange (abort_other_plans, 
@@ -492,29 +490,17 @@
                                                                                 abort_other_plans, 
                                                                                 bool_stop_other_threads);
 
-                // FIXME: This will keep the step plan on the thread stack when we hit a breakpoint while stepping over.
-                // Maybe there should be a parameter to control this.
-                new_plan->SetOkayToDiscard(false);
-
-                process->GetThreadList().SetSelectedThreadByID (thread->GetID());
-                process->Resume ();
             }
             else if (m_step_type == eStepTypeTrace)
             {
-                thread->QueueThreadPlanForStepSingleInstruction (false, abort_other_plans, bool_stop_other_threads);
-                process->GetThreadList().SetSelectedThreadByID (thread->GetID());
-                process->Resume ();
+                new_plan = thread->QueueThreadPlanForStepSingleInstruction (false, abort_other_plans, bool_stop_other_threads);
             }
             else if (m_step_type == eStepTypeTraceOver)
             {
-                thread->QueueThreadPlanForStepSingleInstruction (true, abort_other_plans, bool_stop_other_threads);
-                process->GetThreadList().SetSelectedThreadByID (thread->GetID());
-                process->Resume ();
+                new_plan = thread->QueueThreadPlanForStepSingleInstruction (true, abort_other_plans, bool_stop_other_threads);
             }
             else if (m_step_type == eStepTypeOut)
             {
-                ThreadPlan *new_plan;
-
                 new_plan = thread->QueueThreadPlanForStepOut (abort_other_plans, 
                                                               NULL, 
                                                               false, 
@@ -522,32 +508,46 @@
                                                               eVoteYes, 
                                                               eVoteNoOpinion, 
                                                               thread->GetSelectedFrameIndex());
-                // FIXME: This will keep the step plan on the thread stack when we hit a breakpoint while stepping over.
-                // Maybe there should be a parameter to control this.
-                new_plan->SetOkayToDiscard(false);
-
-                process->GetThreadList().SetSelectedThreadByID (thread->GetID());
-                process->Resume ();
             }
             else
             {
                 result.AppendError ("step type is not supported");
                 result.SetStatus (eReturnStatusFailed);
+                return false;
             }
-            if (synchronous_execution)
+            
+            // If we got a new plan, then set it to be a master plan (User level Plans should be master plans
+            // so that they can be interruptible).  Then resume the process.
+            
+            if (new_plan != NULL)
             {
-                StateType state = process->WaitForProcessToStop (NULL);
-                
-                //EventSP event_sp;
-                //StateType state = process->WaitForStateChangedEvents (NULL, event_sp);
-                //while (! StateIsStoppedState (state))
-                //  {
-                //    state = process->WaitForStateChangedEvents (NULL, event_sp);
-                //  }
+                new_plan->SetIsMasterPlan (true);
+                new_plan->SetOkayToDiscard (false);
+
                 process->GetThreadList().SetSelectedThreadByID (thread->GetID());
-                result.SetDidChangeProcessState (true);
-                result.AppendMessageWithFormat ("Process %llu %s\n", process->GetID(), StateAsCString (state));
-                result.SetStatus (eReturnStatusSuccessFinishNoResult);
+                process->Resume ();
+            
+
+                if (synchronous_execution)
+                {
+                    StateType state = process->WaitForProcessToStop (NULL);
+                    
+                    //EventSP event_sp;
+                    //StateType state = process->WaitForStateChangedEvents (NULL, event_sp);
+                    //while (! StateIsStoppedState (state))
+                    //  {
+                    //    state = process->WaitForStateChangedEvents (NULL, event_sp);
+                    //  }
+                    process->GetThreadList().SetSelectedThreadByID (thread->GetID());
+                    result.SetDidChangeProcessState (true);
+                    result.AppendMessageWithFormat ("Process %llu %s\n", process->GetID(), StateAsCString (state));
+                    result.SetStatus (eReturnStatusSuccessFinishNoResult);
+                }
+            }
+            else
+            {
+                result.AppendError ("Couldn't find thread plan to implement step type.");
+                result.SetStatus (eReturnStatusFailed);
             }
         }
         return result.Succeeded();
@@ -959,7 +959,7 @@
                 return false;
             }
 
-            ThreadPlan *new_plan;
+            ThreadPlan *new_plan = NULL;
 
             if (frame->HasDebugInformation ())
             {
@@ -1027,6 +1027,10 @@
                                                                 address_list.size(), 
                                                                 m_options.m_stop_others, 
                                                                 thread->GetSelectedFrameIndex ());
+                // User level plans should be master plans so they can be interrupted (e.g. by hitting a breakpoint)
+                // and other plans executed by the user (stepping around the breakpoint) and then a "continue"
+                // will resume the original plan.
+                new_plan->SetIsMasterPlan (true);
                 new_plan->SetOkayToDiscard(false);
             }
             else

Modified: lldb/branches/lldb-platform-work/source/Target/Thread.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Target/Thread.cpp?rev=156105&r1=156104&r2=156105&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Target/Thread.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Target/Thread.cpp Thu May  3 16:36:31 2012
@@ -455,8 +455,33 @@
                 }
             }
         }
+        
         if (over_ride_stop)
             should_stop = false;
+
+        // One other potential problem is that we set up a master plan, then stop in before it is complete - for instance
+        // by hitting a breakpoint during a step-over - then do some step/finish/etc operations that wind up
+        // past the end point condition of the initial plan.  We don't want to strand the original plan on the stack,
+        // This code clears stale plans off the stack.
+        
+        if (should_stop)
+        {
+            ThreadPlan *plan_ptr = GetCurrentPlan();
+            while (!PlanIsBasePlan(plan_ptr))
+            {
+                bool stale = plan_ptr->IsPlanStale ();
+                ThreadPlan *examined_plan = plan_ptr;
+                plan_ptr = GetPreviousPlan (examined_plan);
+                
+                if (stale)
+                {
+                    if (log)
+                        log->Printf("Plan %s being discarded in cleanup, it says it is already done.", examined_plan->GetName());
+                    DiscardThreadPlansUpToPlan(examined_plan);
+                }
+            }
+        }
+        
     }
 
     if (log)
@@ -750,10 +775,16 @@
 void
 Thread::DiscardThreadPlansUpToPlan (lldb::ThreadPlanSP &up_to_plan_sp)
 {
+    DiscardThreadPlansUpToPlan (up_to_plan_sp.get());
+}
+
+void
+Thread::DiscardThreadPlansUpToPlan (ThreadPlan *up_to_plan_ptr)
+{
     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
     if (log)
     {
-        log->Printf("Discarding thread plans for thread tid = 0x%4.4llx, up to %p", GetID(), up_to_plan_sp.get());
+        log->Printf("Discarding thread plans for thread tid = 0x%4.4llx, up to %p", GetID(), up_to_plan_ptr);
     }
 
     int stack_size = m_plan_stack.size();
@@ -761,7 +792,7 @@
     // If the input plan is NULL, discard all plans.  Otherwise make sure this plan is in the
     // stack, and if so discard up to and including it.
     
-    if (up_to_plan_sp.get() == NULL)
+    if (up_to_plan_ptr == NULL)
     {
         for (int i = stack_size - 1; i > 0; i--)
             DiscardPlan();
@@ -771,7 +802,7 @@
         bool found_it = false;
         for (int i = stack_size - 1; i > 0; i--)
         {
-            if (m_plan_stack[i] == up_to_plan_sp)
+            if (m_plan_stack[i].get() == up_to_plan_ptr)
                 found_it = true;
         }
         if (found_it)
@@ -779,7 +810,7 @@
             bool last_one = false;
             for (int i = stack_size - 1; i > 0 && !last_one ; i--)
             {
-                if (GetCurrentPlan() == up_to_plan_sp.get())
+                if (GetCurrentPlan() == up_to_plan_ptr)
                     last_one = true;
                 DiscardPlan();
             }

Modified: lldb/branches/lldb-platform-work/source/Target/ThreadPlan.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Target/ThreadPlan.cpp?rev=156105&r1=156104&r2=156105&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Target/ThreadPlan.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Target/ThreadPlan.cpp Thu May  3 16:36:31 2012
@@ -36,7 +36,7 @@
     m_plan_complete_mutex (Mutex::eMutexTypeRecursive),
     m_plan_complete (false),
     m_plan_private (false),
-    m_okay_to_discard (false),
+    m_okay_to_discard (true),
     m_is_master_plan (false),
     m_plan_succeeded(true)
 {

Modified: lldb/branches/lldb-platform-work/source/Target/ThreadPlanStepInstruction.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Target/ThreadPlanStepInstruction.cpp?rev=156105&r1=156104&r2=156105&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Target/ThreadPlanStepInstruction.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Target/ThreadPlanStepInstruction.cpp Thu May  3 16:36:31 2012
@@ -131,7 +131,13 @@
                     s.Address (return_addr, m_thread.CalculateTarget()->GetArchitecture().GetAddressByteSize());
                     log->Printf("%s.", s.GetData());
                 }
-                m_thread.QueueThreadPlanForStepOut(false, NULL, true, m_stop_other_threads, eVoteNo, eVoteNoOpinion, 0);
+                m_thread.QueueThreadPlanForStepOut(false,
+                                                   NULL,
+                                                   true,
+                                                   m_stop_other_threads,
+                                                   eVoteNo,
+                                                   eVoteNoOpinion,
+                                                   0);
                 return false;
             }
             else

Modified: lldb/branches/lldb-platform-work/source/Target/ThreadPlanStepOut.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Target/ThreadPlanStepOut.cpp?rev=156105&r1=156104&r2=156105&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Target/ThreadPlanStepOut.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Target/ThreadPlanStepOut.cpp Thu May  3 16:36:31 2012
@@ -81,7 +81,6 @@
                                                             eVoteNoOpinion, 
                                                             eVoteNoOpinion, 
                                                             frame_idx - 1));
-            m_step_out_plan_sp->SetOkayToDiscard(true);
         }
         else
         {
@@ -468,3 +467,17 @@
         }
     }
 }
+
+bool
+ThreadPlanStepOut::IsPlanStale()
+{
+    // If we are still lower on the stack than the frame we are returning to, then
+    // there's something for us to do.  Otherwise, we're stale.
+    
+    StackID frame_zero_id = m_thread.GetStackFrameAtIndex(0)->GetStackID();
+    if (frame_zero_id < m_step_out_to_id)
+        return false;
+    else
+        return true;
+}
+

Modified: lldb/branches/lldb-platform-work/source/Target/ThreadPlanStepOverRange.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Target/ThreadPlanStepOverRange.cpp?rev=156105&r1=156104&r2=156105&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Target/ThreadPlanStepOverRange.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Target/ThreadPlanStepOverRange.cpp Thu May  3 16:36:31 2012
@@ -38,15 +38,10 @@
     Thread &thread,
     const AddressRange &range,
     const SymbolContext &addr_context,
-    lldb::RunMode stop_others,
-    bool okay_to_discard
+    lldb::RunMode stop_others
 ) :
     ThreadPlanStepRange (ThreadPlan::eKindStepOverRange, "Step range stepping over", thread, range, addr_context, stop_others)
 {
-    // Step over range plans can be master plans, since you could hit a breakpoint while stepping over, step around
-    // a bit, then continue to finish up the step over.
-    SetIsMasterPlan (true);
-    SetOkayToDiscard (okay_to_discard);
 }
 
 ThreadPlanStepOverRange::~ThreadPlanStepOverRange ()

Modified: lldb/branches/lldb-platform-work/source/Target/ThreadPlanStepRange.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Target/ThreadPlanStepRange.cpp?rev=156105&r1=156104&r2=156105&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Target/ThreadPlanStepRange.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Target/ThreadPlanStepRange.cpp Thu May  3 16:36:31 2012
@@ -403,3 +403,30 @@
     }
 
 }
+
+bool
+ThreadPlanStepRange::IsPlanStale ()
+{
+    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
+    FrameComparison frame_order = CompareCurrentFrameToStartFrame();
+    
+    if (frame_order == eFrameCompareOlder)
+    {
+        if (log)
+        {
+            log->Printf("ThreadPlanStepRange::IsPlanStale returning true, we've stepped out.");
+        }
+        return true;
+    }
+    else if (frame_order == eFrameCompareEqual && InSymbol())
+    {
+        // If we are not in a place we should step through, we've gotten stale.
+        // One tricky bit here is that some stubs don't push a frame, so we should.  
+        // check that we are in the same symbol.          
+        if (!InRange())
+        {
+            return true;
+        }
+    }
+    return false;
+}

Modified: lldb/branches/lldb-platform-work/source/Target/ThreadPlanStepUntil.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Target/ThreadPlanStepUntil.cpp?rev=156105&r1=156104&r2=156105&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Target/ThreadPlanStepUntil.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Target/ThreadPlanStepUntil.cpp Thu May  3 16:36:31 2012
@@ -51,12 +51,6 @@
     m_until_points (),
     m_stop_others (stop_others)
 {
-
-    // Step until plans can be master plans, since you could hit a breakpoint while stepping to the stop point, step around
-    // a bit, then continue to finish up the step until.
-    SetIsMasterPlan (true);
-    SetOkayToDiscard(true);
-    
     // Stash away our "until" addresses:
     TargetSP target_sp (m_thread.CalculateTarget());
 

Modified: lldb/branches/lldb-platform-work/tools/debugserver/debugserver.xcodeproj/project.pbxproj
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/tools/debugserver/debugserver.xcodeproj/project.pbxproj?rev=156105&r1=156104&r2=156105&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/tools/debugserver/debugserver.xcodeproj/project.pbxproj (original)
+++ lldb/branches/lldb-platform-work/tools/debugserver/debugserver.xcodeproj/project.pbxproj Thu May  3 16:36:31 2012
@@ -514,10 +514,7 @@
 					armv7,
 					armv7s,
 				);
-				"ARCHS[sdk=macosx*]" = (
-					x86_64,
-					i386,
-				);
+				"ARCHS[sdk=macosx*]" = "$(ARCHS_STANDARD_64_BIT)";
 				CURRENT_PROJECT_VERSION = 186;
 				DEAD_CODE_STRIPPING = YES;
 				GCC_VERSION = com.apple.compilers.llvm.clang.1_0;





More information about the lldb-commits mailing list