[Lldb-commits] [lldb] r174793 - Reworked the way Process::RunThreadPlan and the ThreadPlanCallFunction interoperate to fix problems where

Jim Ingham jingham at apple.com
Fri Feb 8 17:29:05 PST 2013


Author: jingham
Date: Fri Feb  8 19:29:05 2013
New Revision: 174793

URL: http://llvm.org/viewvc/llvm-project?rev=174793&view=rev
Log:
Reworked the way Process::RunThreadPlan and the ThreadPlanCallFunction interoperate to fix problems where
hitting auto-continue signals while running a thread plan would cause us to lose control of the debug 
session.

<rdar://problem/12993641>

Modified:
    lldb/trunk/include/lldb/API/SBExpressionOptions.h
    lldb/trunk/include/lldb/API/SBProcess.h
    lldb/trunk/include/lldb/Target/Process.h
    lldb/trunk/include/lldb/Target/StopInfo.h
    lldb/trunk/include/lldb/Target/ThreadPlan.h
    lldb/trunk/include/lldb/Target/ThreadPlanBase.h
    lldb/trunk/include/lldb/Target/ThreadPlanCallFunction.h
    lldb/trunk/include/lldb/Target/ThreadPlanRunToAddress.h
    lldb/trunk/include/lldb/Target/ThreadPlanStepInRange.h
    lldb/trunk/include/lldb/Target/ThreadPlanStepInstruction.h
    lldb/trunk/include/lldb/Target/ThreadPlanStepOut.h
    lldb/trunk/include/lldb/Target/ThreadPlanStepOverBreakpoint.h
    lldb/trunk/include/lldb/Target/ThreadPlanStepOverRange.h
    lldb/trunk/include/lldb/Target/ThreadPlanStepThrough.h
    lldb/trunk/include/lldb/Target/ThreadPlanStepUntil.h
    lldb/trunk/scripts/Python/interface/SBExpressionOptions.i
    lldb/trunk/scripts/Python/interface/SBProcess.i
    lldb/trunk/source/API/SBProcess.cpp
    lldb/trunk/source/Commands/CommandObjectProcess.cpp
    lldb/trunk/source/Expression/ClangUserExpression.cpp
    lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.cpp
    lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.h
    lldb/trunk/source/Target/Process.cpp
    lldb/trunk/source/Target/StopInfo.cpp
    lldb/trunk/source/Target/Thread.cpp
    lldb/trunk/source/Target/ThreadPlanBase.cpp
    lldb/trunk/source/Target/ThreadPlanCallFunction.cpp
    lldb/trunk/source/Target/ThreadPlanRunToAddress.cpp
    lldb/trunk/source/Target/ThreadPlanStepInRange.cpp
    lldb/trunk/source/Target/ThreadPlanStepInstruction.cpp
    lldb/trunk/source/Target/ThreadPlanStepOut.cpp
    lldb/trunk/source/Target/ThreadPlanStepOverBreakpoint.cpp
    lldb/trunk/source/Target/ThreadPlanStepOverRange.cpp
    lldb/trunk/source/Target/ThreadPlanStepThrough.cpp
    lldb/trunk/source/Target/ThreadPlanStepUntil.cpp
    lldb/trunk/test/functionalities/conditional_break/conditional_break.py
    lldb/trunk/tools/driver/Driver.cpp

Modified: lldb/trunk/include/lldb/API/SBExpressionOptions.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/API/SBExpressionOptions.h?rev=174793&r1=174792&r2=174793&view=diff
==============================================================================
--- lldb/trunk/include/lldb/API/SBExpressionOptions.h (original)
+++ lldb/trunk/include/lldb/API/SBExpressionOptions.h Fri Feb  8 19:29:05 2013
@@ -40,13 +40,13 @@ public:
     GetUnwindOnError () const;
     
     void
-    SetUnwindOnError (bool unwind = false);
+    SetUnwindOnError (bool unwind = true);
     
     bool
     GetIgnoreBreakpoints () const;
     
     void
-    SetIgnoreBreakpoints (bool ignore = false);
+    SetIgnoreBreakpoints (bool ignore = true);
     
     lldb::DynamicValueType
     GetFetchDynamicValue () const;

Modified: lldb/trunk/include/lldb/API/SBProcess.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/API/SBProcess.h?rev=174793&r1=174792&r2=174793&view=diff
==============================================================================
--- lldb/trunk/include/lldb/API/SBProcess.h (original)
+++ lldb/trunk/include/lldb/API/SBProcess.h Fri Feb  8 19:29:05 2013
@@ -234,6 +234,12 @@ public:
 
     static bool
     GetRestartedFromEvent (const lldb::SBEvent &event);
+    
+    static size_t
+    GetNumRestartedReasonsFromEvent (const lldb::SBEvent &event);
+    
+    static const char *
+    GetRestartedReasonAtIndexFromEvent (const lldb::SBEvent &event, size_t idx);
 
     static lldb::SBProcess
     GetProcessFromEvent (const lldb::SBEvent &event);

Modified: lldb/trunk/include/lldb/Target/Process.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/Process.h?rev=174793&r1=174792&r2=174793&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Target/Process.h (original)
+++ lldb/trunk/include/lldb/Target/Process.h Fri Feb  8 19:29:05 2013
@@ -1446,6 +1446,22 @@ public:
             {
                 return m_restarted;
             }
+        
+            size_t
+            GetNumRestartedReasons ()
+            {
+                return m_restarted_reasons.size();
+            }
+        
+            const char *
+            GetRestartedReasonAtIndex(size_t idx)
+            {
+                if (idx > m_restarted_reasons.size())
+                    return NULL;
+                else
+                    return m_restarted_reasons[idx].c_str();
+            }
+        
             bool
             GetInterrupted () const
             {
@@ -1469,6 +1485,15 @@ public:
 
             static bool
             GetRestartedFromEvent (const Event *event_ptr);
+        
+            static size_t
+            GetNumRestartedReasons(const Event *event_ptr);
+        
+            static const char *
+            GetRestartedReasonAtIndex(const Event *event_ptr, size_t idx);
+        
+            static void
+            AddRestartedReason (Event *event_ptr, const char *reason);
 
             static void
             SetRestartedInEvent (Event *event_ptr, bool new_value);
@@ -1499,9 +1524,15 @@ public:
             {
                 m_interrupted = new_value;
             }
+            void
+            AddRestartedReason (const char *reason)
+            {
+                m_restarted_reasons.push_back(reason);
+            }
 
             lldb::ProcessSP m_process_sp;
             lldb::StateType m_state;
+            std::vector<std::string> m_restarted_reasons;
             bool m_restarted;  // For "eStateStopped" events, this is true if the target was automatically restarted.
             int m_update_state;
             bool m_interrupted;
@@ -3543,7 +3574,8 @@ protected:
     ReadWriteLock               m_run_lock;
     Predicate<bool>             m_currently_handling_event;
     bool                        m_finalize_called;
-
+    lldb::StateType             m_last_broadcast_state;   /// This helps with the Public event coalescing in ShouldBroadcastEvent.
+    
     enum {
         eCanJITDontKnow= 0,
         eCanJITYes,
@@ -3637,7 +3669,7 @@ private:
     // For Process only
     //------------------------------------------------------------------
     void ControlPrivateStateThread (uint32_t signal);
-
+    
     DISALLOW_COPY_AND_ASSIGN (Process);
 
 };

Modified: lldb/trunk/include/lldb/Target/StopInfo.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/StopInfo.h?rev=174793&r1=174792&r2=174793&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Target/StopInfo.h (original)
+++ lldb/trunk/include/lldb/Target/StopInfo.h Fri Feb  8 19:29:05 2013
@@ -106,7 +106,32 @@ public:
         else
             m_description.clear();
     }
-
+    
+    // Sometimes the thread plan logic will know that it wants a given stop to stop or not,
+    // regardless of what the ordinary logic for that StopInfo would dictate.  The main example
+    // of this is the ThreadPlanCallFunction, which for instance knows - based on how that particular
+    // expression was executed - whether it wants all breakpoints to auto-continue or not.
+    // Use OverrideShouldStop on the StopInfo to implement this.
+    
+    void
+    OverrideShouldStop (bool override_value)
+    {
+        m_override_set = true;
+        m_override_value = override_value;
+    }
+    
+    bool
+    GetOverrideShouldStop()
+    {
+        return m_override_set;
+    }
+    
+    bool
+    GetOverriddenShouldStopValue ()
+    {
+        return m_override_value;
+    }
+    
     static lldb::StopInfoSP
     CreateStopReasonWithBreakpointSiteID (Thread &thread, lldb::break_id_t break_id);
 
@@ -138,6 +163,7 @@ public:
 protected:
     // Perform any action that is associated with this stop.  This is done as the
     // Event is removed from the event queue.  ProcessEventData::DoOnRemoval does the job.
+ 
     virtual void
     PerformAction (Event *event_ptr)
     {
@@ -163,6 +189,8 @@ protected:
     uint32_t        m_resume_id; // This is the resume ID when we made this stop ID.
     uint64_t        m_value;    // A generic value that can be used for things pertaining to this stop info
     std::string     m_description; // A textual description describing this stop.
+    bool            m_override_set;
+    bool            m_override_value;
     
     // This determines whether the target has run since this stop info.
     // N.B. running to evaluate a user expression does not count. 

Modified: lldb/trunk/include/lldb/Target/ThreadPlan.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/ThreadPlan.h?rev=174793&r1=174792&r2=174793&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Target/ThreadPlan.h (original)
+++ lldb/trunk/include/lldb/Target/ThreadPlan.h Fri Feb  8 19:29:05 2013
@@ -332,7 +332,7 @@ public:
     ValidatePlan (Stream *error) = 0;
 
     virtual bool
-    PlanExplainsStop () = 0;
+    PlanExplainsStop (Event *event_ptr) = 0;
     
     bool
     TracerExplainsStop ()

Modified: lldb/trunk/include/lldb/Target/ThreadPlanBase.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/ThreadPlanBase.h?rev=174793&r1=174792&r2=174793&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Target/ThreadPlanBase.h (original)
+++ lldb/trunk/include/lldb/Target/ThreadPlanBase.h Fri Feb  8 19:29:05 2013
@@ -35,7 +35,7 @@ public:
 
     virtual void GetDescription (Stream *s, lldb::DescriptionLevel level);
     virtual bool ValidatePlan (Stream *error);
-    virtual bool PlanExplainsStop ();
+    virtual bool PlanExplainsStop (Event *event_ptr);
     virtual bool ShouldStop (Event *event_ptr);
     virtual bool StopOthers ();
     virtual lldb::StateType GetPlanRunState ();

Modified: lldb/trunk/include/lldb/Target/ThreadPlanCallFunction.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/ThreadPlanCallFunction.h?rev=174793&r1=174792&r2=174793&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Target/ThreadPlanCallFunction.h (original)
+++ lldb/trunk/include/lldb/Target/ThreadPlanCallFunction.h Fri Feb  8 19:29:05 2013
@@ -59,10 +59,13 @@ public:
     ValidatePlan (Stream *error);
 
     virtual bool
-    PlanExplainsStop ();
+    PlanExplainsStop (Event *event_ptr);
 
     virtual bool
     ShouldStop (Event *event_ptr);
+    
+    virtual Vote
+    ShouldReportStop(Event *event_ptr);
 
     virtual bool
     StopOthers ();

Modified: lldb/trunk/include/lldb/Target/ThreadPlanRunToAddress.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/ThreadPlanRunToAddress.h?rev=174793&r1=174792&r2=174793&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Target/ThreadPlanRunToAddress.h (original)
+++ lldb/trunk/include/lldb/Target/ThreadPlanRunToAddress.h Fri Feb  8 19:29:05 2013
@@ -47,7 +47,7 @@ public:
     ValidatePlan (Stream *error);
 
     virtual bool
-    PlanExplainsStop ();
+    PlanExplainsStop (Event *event_ptr);
 
     virtual bool
     ShouldStop (Event *event_ptr);

Modified: lldb/trunk/include/lldb/Target/ThreadPlanStepInRange.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/ThreadPlanStepInRange.h?rev=174793&r1=174792&r2=174793&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Target/ThreadPlanStepInRange.h (original)
+++ lldb/trunk/include/lldb/Target/ThreadPlanStepInRange.h Fri Feb  8 19:29:05 2013
@@ -61,7 +61,7 @@ public:
     SetDefaultFlagValue (uint32_t new_value);
 
     virtual bool
-    PlanExplainsStop ();
+    PlanExplainsStop (Event *event_ptr);
 
     virtual bool WillResume (lldb::StateType resume_state, bool current_plan);
     

Modified: lldb/trunk/include/lldb/Target/ThreadPlanStepInstruction.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/ThreadPlanStepInstruction.h?rev=174793&r1=174792&r2=174793&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Target/ThreadPlanStepInstruction.h (original)
+++ lldb/trunk/include/lldb/Target/ThreadPlanStepInstruction.h Fri Feb  8 19:29:05 2013
@@ -27,7 +27,7 @@ public:
 
     virtual void GetDescription (Stream *s, lldb::DescriptionLevel level);
     virtual bool ValidatePlan (Stream *error);
-    virtual bool PlanExplainsStop ();
+    virtual bool PlanExplainsStop (Event *event_ptr);
     virtual bool ShouldStop (Event *event_ptr);
     virtual bool StopOthers ();
     virtual lldb::StateType GetPlanRunState ();

Modified: lldb/trunk/include/lldb/Target/ThreadPlanStepOut.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/ThreadPlanStepOut.h?rev=174793&r1=174792&r2=174793&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Target/ThreadPlanStepOut.h (original)
+++ lldb/trunk/include/lldb/Target/ThreadPlanStepOut.h Fri Feb  8 19:29:05 2013
@@ -34,7 +34,7 @@ public:
 
     virtual void GetDescription (Stream *s, lldb::DescriptionLevel level);
     virtual bool ValidatePlan (Stream *error);
-    virtual bool PlanExplainsStop ();
+    virtual bool PlanExplainsStop (Event *event_ptr);
     virtual bool ShouldStop (Event *event_ptr);
     virtual bool StopOthers ();
     virtual lldb::StateType GetPlanRunState ();

Modified: lldb/trunk/include/lldb/Target/ThreadPlanStepOverBreakpoint.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/ThreadPlanStepOverBreakpoint.h?rev=174793&r1=174792&r2=174793&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Target/ThreadPlanStepOverBreakpoint.h (original)
+++ lldb/trunk/include/lldb/Target/ThreadPlanStepOverBreakpoint.h Fri Feb  8 19:29:05 2013
@@ -27,7 +27,7 @@ public:
     ThreadPlanStepOverBreakpoint (Thread &thread);
     virtual void GetDescription (Stream *s, lldb::DescriptionLevel level);
     virtual bool ValidatePlan (Stream *error);
-    virtual bool PlanExplainsStop ();
+    virtual bool PlanExplainsStop (Event *event_ptr);
     virtual bool ShouldStop (Event *event_ptr);
     virtual bool StopOthers ();
     virtual lldb::StateType GetPlanRunState ();

Modified: lldb/trunk/include/lldb/Target/ThreadPlanStepOverRange.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/ThreadPlanStepOverRange.h?rev=174793&r1=174792&r2=174793&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Target/ThreadPlanStepOverRange.h (original)
+++ lldb/trunk/include/lldb/Target/ThreadPlanStepOverRange.h Fri Feb  8 19:29:05 2013
@@ -34,7 +34,7 @@ public:
 
     virtual void GetDescription (Stream *s, lldb::DescriptionLevel level);
     virtual bool ShouldStop (Event *event_ptr);
-    virtual bool PlanExplainsStop ();
+    virtual bool PlanExplainsStop (Event *event_ptr);
     virtual bool WillResume (lldb::StateType resume_state, bool current_plan);
     
 protected:

Modified: lldb/trunk/include/lldb/Target/ThreadPlanStepThrough.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/ThreadPlanStepThrough.h?rev=174793&r1=174792&r2=174793&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Target/ThreadPlanStepThrough.h (original)
+++ lldb/trunk/include/lldb/Target/ThreadPlanStepThrough.h Fri Feb  8 19:29:05 2013
@@ -26,7 +26,7 @@ public:
 
     virtual void GetDescription (Stream *s, lldb::DescriptionLevel level);
     virtual bool ValidatePlan (Stream *error);
-    virtual bool PlanExplainsStop ();
+    virtual bool PlanExplainsStop (Event *event_ptr);
     virtual bool ShouldStop (Event *event_ptr);
     virtual bool StopOthers ();
     virtual lldb::StateType GetPlanRunState ();

Modified: lldb/trunk/include/lldb/Target/ThreadPlanStepUntil.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/ThreadPlanStepUntil.h?rev=174793&r1=174792&r2=174793&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Target/ThreadPlanStepUntil.h (original)
+++ lldb/trunk/include/lldb/Target/ThreadPlanStepUntil.h Fri Feb  8 19:29:05 2013
@@ -27,7 +27,7 @@ public:
 
     virtual void GetDescription (Stream *s, lldb::DescriptionLevel level);
     virtual bool ValidatePlan (Stream *error);
-    virtual bool PlanExplainsStop ();
+    virtual bool PlanExplainsStop (Event *event_ptr);
     virtual bool ShouldStop (Event *event_ptr);
     virtual bool StopOthers ();
     virtual lldb::StateType GetPlanRunState ();

Modified: lldb/trunk/scripts/Python/interface/SBExpressionOptions.i
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/scripts/Python/interface/SBExpressionOptions.i?rev=174793&r1=174792&r2=174793&view=diff
==============================================================================
--- lldb/trunk/scripts/Python/interface/SBExpressionOptions.i (original)
+++ lldb/trunk/scripts/Python/interface/SBExpressionOptions.i Fri Feb  8 19:29:05 2013
@@ -39,7 +39,7 @@ public:
     %feature("docstring", "Sets whether to unwind the expression stack on error.") SetUnwindOnError;
     
     void
-    SetUnwindOnError (bool unwind = false);
+    SetUnwindOnError (bool unwind = true);
     
     bool
     GetIgnoreBreakpoints () const;
@@ -47,7 +47,7 @@ public:
     %feature("docstring", "Sets whether to ignore breakpoint hits while running expressions.") SetUnwindOnError;
     
     void
-    SetIgnoreBreakpoints (bool ignore = false);
+    SetIgnoreBreakpoints (bool ignore = true);
     
     lldb::DynamicValueType
     GetFetchDynamicValue () const;

Modified: lldb/trunk/scripts/Python/interface/SBProcess.i
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/scripts/Python/interface/SBProcess.i?rev=174793&r1=174792&r2=174793&view=diff
==============================================================================
--- lldb/trunk/scripts/Python/interface/SBProcess.i (original)
+++ lldb/trunk/scripts/Python/interface/SBProcess.i Fri Feb  8 19:29:05 2013
@@ -328,6 +328,12 @@ public:
     static bool
     GetRestartedFromEvent (const lldb::SBEvent &event);
 
+    static size_t
+    GetNumRestartedReasonsFromEvent (const lldb::SBEvent &event);
+    
+    static const char *
+    GetRestartedReasonAtIndexFromEvent (const lldb::SBEvent &event, size_t idx);
+
     static lldb::SBProcess
     GetProcessFromEvent (const lldb::SBEvent &event);
 

Modified: lldb/trunk/source/API/SBProcess.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/API/SBProcess.cpp?rev=174793&r1=174792&r2=174793&view=diff
==============================================================================
--- lldb/trunk/source/API/SBProcess.cpp (original)
+++ lldb/trunk/source/API/SBProcess.cpp Fri Feb  8 19:29:05 2013
@@ -909,6 +909,18 @@ SBProcess::GetRestartedFromEvent (const
     return Process::ProcessEventData::GetRestartedFromEvent (event.get());
 }
 
+size_t
+SBProcess::GetNumRestartedReasonsFromEvent (const lldb::SBEvent &event)
+{
+    return Process::ProcessEventData::GetNumRestartedReasons(event.get());
+}
+
+const char *
+SBProcess::GetRestartedReasonAtIndexFromEvent (const lldb::SBEvent &event, size_t idx)
+{
+    return Process::ProcessEventData::GetRestartedReasonAtIndex(event.get(), idx);
+}
+
 SBProcess
 SBProcess::GetProcessFromEvent (const SBEvent &event)
 {

Modified: lldb/trunk/source/Commands/CommandObjectProcess.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectProcess.cpp?rev=174793&r1=174792&r2=174793&view=diff
==============================================================================
--- lldb/trunk/source/Commands/CommandObjectProcess.cpp (original)
+++ lldb/trunk/source/Commands/CommandObjectProcess.cpp Fri Feb  8 19:29:05 2013
@@ -199,6 +199,11 @@ protected:
         if (environment.GetArgumentCount() > 0)
             m_options.launch_info.GetEnvironmentEntries ().AppendArguments (environment);
 
+        // Get the value of synchronous execution here.  If you wait till after you have started to
+        // run, then you could have hit a breakpoint, whose command might switch the value, and
+        // then you'll pick up that incorrect value.
+        bool synchronous_execution = m_interpreter.GetSynchronous ();
+
         // Finalize the file actions, and if none were given, default to opening
         // up a pseudo terminal
         const bool default_to_use_pty = true;
@@ -258,7 +263,6 @@ protected:
                     error = process->Resume();
                     if (error.Success())
                     {
-                        bool synchronous_execution = m_interpreter.GetSynchronous ();
                         if (synchronous_execution)
                         {
                             state = process->WaitForProcessToStop (NULL);

Modified: lldb/trunk/source/Expression/ClangUserExpression.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/ClangUserExpression.cpp?rev=174793&r1=174792&r2=174793&view=diff
==============================================================================
--- lldb/trunk/source/Expression/ClangUserExpression.cpp (original)
+++ lldb/trunk/source/Expression/ClangUserExpression.cpp Fri Feb  8 19:29:05 2013
@@ -703,7 +703,7 @@ ClangUserExpression::Execute (Stream &er
         }
         
         const bool stop_others = true;
-        const bool try_all_threads = true;
+        const bool try_all_threads = run_others;
         
         Address wrapper_address (m_jit_start_addr);
         lldb::ThreadPlanSP call_plan_sp(new ThreadPlanCallUserExpression (exe_ctx.GetThreadRef(), 

Modified: lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.cpp?rev=174793&r1=174792&r2=174793&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.cpp (original)
+++ lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.cpp Fri Feb  8 19:29:05 2013
@@ -126,7 +126,7 @@ AppleThreadPlanStepThroughObjCTrampoline
 }
 
 bool
-AppleThreadPlanStepThroughObjCTrampoline::PlanExplainsStop ()
+AppleThreadPlanStepThroughObjCTrampoline::PlanExplainsStop (Event *event_ptr)
 {
     // If we get asked to explain the stop it will be because something went
     // wrong (like the implementation for selector function crashed...  We're going

Modified: lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.h?rev=174793&r1=174792&r2=174793&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.h (original)
+++ lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.h Fri Feb  8 19:29:05 2013
@@ -46,7 +46,7 @@ public:
     ValidatePlan (Stream *error);
 
     virtual bool
-    PlanExplainsStop ();
+    PlanExplainsStop (Event *event_ptr);
 
 
     virtual lldb::StateType

Modified: lldb/trunk/source/Target/Process.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/Process.cpp?rev=174793&r1=174792&r2=174793&view=diff
==============================================================================
--- lldb/trunk/source/Target/Process.cpp (original)
+++ lldb/trunk/source/Target/Process.cpp Fri Feb  8 19:29:05 2013
@@ -1021,6 +1021,7 @@ Process::Process(Target &target, Listene
     m_run_lock (),
     m_currently_handling_event(false),
     m_finalize_called(false),
+    m_last_broadcast_state (eStateInvalid),
     m_can_jit(eCanJITDontKnow)
 {
     CheckInWithManager ();
@@ -3146,9 +3147,9 @@ Process::ConnectRemote (Stream *strm, co
 Error
 Process::PrivateResume ()
 {
-    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS|LIBLLDB_LOG_STEP));
+    LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_PROCESS|LIBLLDB_LOG_STEP));
     if (log)
-        log->Printf("Process::Resume() m_stop_id = %u, public state: %s private state: %s", 
+        log->Printf("Process::PrivateResume() m_stop_id = %u, public state: %s private state: %s", 
                     m_mod_id.GetStopID(),
                     StateAsCString(m_public_state.GetValue()),
                     StateAsCString(m_private_state.GetValue()));
@@ -3170,7 +3171,7 @@ Process::PrivateResume ()
             // Last thing, do the PreResumeActions.
             if (!RunPreResumeActions())
             {
-                error.SetErrorStringWithFormat ("Process::Resume PreResumeActions failed, not resuming.");
+                error.SetErrorStringWithFormat ("Process::PrivateResume PreResumeActions failed, not resuming.");
             }
             else
             {
@@ -3197,7 +3198,7 @@ Process::PrivateResume ()
         }
     }
     else if (log)
-        log->Printf ("Process::WillResume() got an error \"%s\".", error.AsCString("<unknown error>"));
+        log->Printf ("Process::PrivateResume() got an error \"%s\".", error.AsCString("<unknown error>"));
     return error;
 }
 
@@ -3422,8 +3423,8 @@ Process::ShouldBroadcastEvent (Event *ev
 {
     const StateType state = Process::ProcessEventData::GetStateFromEvent (event_ptr);
     bool return_value = true;
-    LogSP log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EVENTS));
-
+    LogSP log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_EVENTS | LIBLLDB_LOG_PROCESS));
+    
     switch (state)
     {
         case eStateConnected:
@@ -3448,7 +3449,7 @@ Process::ShouldBroadcastEvent (Event *ev
             // stopped -> running: Report except when there is one or more no votes
             //     and no yes votes.
             SynchronouslyNotifyStateChanged (state);
-            switch (m_public_state.GetValue())
+            switch (m_last_broadcast_state)
             {
                 case eStateRunning:
                 case eStateStepping:
@@ -3490,32 +3491,50 @@ Process::ShouldBroadcastEvent (Event *ev
             if (ProcessEventData::GetInterruptedFromEvent (event_ptr))
             {
                 if (log)
-                    log->Printf ("Process::ShouldBroadcastEvent (%p) stopped due to an interrupt, state: %s", event_ptr, StateAsCString(state));
-                return true;
+                    log->Printf ("Process::ShouldBroadcastEvent (%p) stopped due to an interrupt, state: %s",
+                                 event_ptr,
+                                 StateAsCString(state));
+                return_value = true;
             }
             else
             {
-
-                if (m_thread_list.ShouldStop (event_ptr) == false)
+                // It makes no sense to ask "ShouldStop" if we've already been restarted...
+                // Asking the thread list is also not likely to go well, since we are running again.
+                // So in that case just report the event.
+                
+                bool was_restarted = ProcessEventData::GetRestartedFromEvent (event_ptr);
+                bool should_resume = false;
+                if (!was_restarted)
+                    should_resume = m_thread_list.ShouldStop (event_ptr) == false;
+                if (was_restarted || should_resume)
                 {
-                    // ShouldStop may have restarted the target already.  If so, don't
-                    // resume it twice.
-                    bool was_restarted = ProcessEventData::GetRestartedFromEvent (event_ptr);
-                    switch (m_thread_list.ShouldReportStop (event_ptr))
+                    Vote stop_vote = m_thread_list.ShouldReportStop (event_ptr);
+                    if (log)
+                        log->Printf ("Process::ShouldBroadcastEvent: should_stop: %i state: %s was_restarted: %i stop_vote: %d.",
+                                     should_resume,
+                                     StateAsCString(state),
+                                     was_restarted,
+                                     stop_vote);
+                    
+                    switch (stop_vote)
                     {
                         case eVoteYes:
-                            Process::ProcessEventData::SetRestartedInEvent (event_ptr, true);
-                            // Intentional fall-through here.
+                            return_value = true;
+                            break;
                         case eVoteNoOpinion:
                         case eVoteNo:
                             return_value = false;
                             break;
                     }
-
-                    if (log)
-                        log->Printf ("Process::ShouldBroadcastEvent (%p) Restarting process from state: %s", event_ptr, StateAsCString(state));
+                    
                     if (!was_restarted)
+                    {
+                        if (log)
+                            log->Printf ("Process::ShouldBroadcastEvent (%p) Restarting process from state: %s", event_ptr, StateAsCString(state));
+                        ProcessEventData::SetRestartedInEvent(event_ptr, true);
                         PrivateResume ();
+                    }
+                    
                 }
                 else
                 {
@@ -3524,10 +3543,25 @@ Process::ShouldBroadcastEvent (Event *ev
                 }
             }
         }
+        break;
     }
-
-    if (log)
-        log->Printf ("Process::ShouldBroadcastEvent (%p) => %s - %s", event_ptr, StateAsCString(state), return_value ? "YES" : "NO");
+    
+    // We do some coalescing of events (for instance two consecutive running events get coalesced.)
+    // But we only coalesce against events we actually broadcast.  So we use m_last_broadcast_state
+    // to track that.  NB - you can't use "m_public_state.GetValue()" for that purpose, as was originally done,
+    // because the PublicState reflects the last event pulled off the queue, and there may be several
+    // events stacked up on the queue unserviced.  So the PublicState may not reflect the last broadcasted event
+    // yet.  m_last_broadcast_state gets updated here.
+    
+    if (return_value)
+        m_last_broadcast_state = state;
+    
+    if (log)
+        log->Printf ("Process::ShouldBroadcastEvent (%p) => new state: %s, last broadcast state: %s - %s",
+                     event_ptr,
+                     StateAsCString(state),
+                     StateAsCString(m_last_broadcast_state),
+                     return_value ? "YES" : "NO");
     return return_value;
 }
 
@@ -3585,7 +3619,7 @@ Process::StopPrivateStateThread ()
     {
         LogSP log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
         if (log)
-            printf ("Went to stop the private state thread, but it was already invalid.");
+            log->Printf ("Went to stop the private state thread, but it was already invalid.");
     }
 }
 
@@ -3667,6 +3701,9 @@ Process::HandlePrivateEvent (EventSP &ev
     if (m_next_event_action_ap.get() != NULL)
     {
         NextEventAction::EventActionResult action_result = m_next_event_action_ap->PerformAction(event_sp);
+        if (log)
+            log->Printf ("Ran next event action, result was %d.", action_result);
+        
         switch (action_result)
         {
             case NextEventAction::eEventActionSuccess:
@@ -3871,7 +3908,7 @@ Process::ProcessEventData::DoOnRemoval (
     
     if (m_update_state != 1)
         return;
-        
+    
     m_process_sp->SetPublicState (m_state);
         
     // If we're stopped and haven't restarted, then do the breakpoint commands here:
@@ -3926,20 +3963,29 @@ Process::ProcessEventData::DoOnRemoval (
             StopInfoSP stop_info_sp = thread_sp->GetStopInfo ();
             if (stop_info_sp && stop_info_sp->IsValid())
             {
-                stop_info_sp->PerformAction(event_ptr);
-                // The stop action might restart the target.  If it does, then we want to mark that in the
-                // event so that whoever is receiving it will know to wait for the running event and reflect
-                // that state appropriately.
-                // We also need to stop processing actions, since they aren't expecting the target to be running.
-                
-                // FIXME: we might have run.
-                if (stop_info_sp->HasTargetRunSinceMe())
+                bool this_thread_wants_to_stop;
+                if (stop_info_sp->GetOverrideShouldStop())
                 {
-                    SetRestarted (true);
-                    break;
+                    this_thread_wants_to_stop = stop_info_sp->GetOverriddenShouldStopValue();
+                }
+                else
+                {
+                    stop_info_sp->PerformAction(event_ptr);
+                    // The stop action might restart the target.  If it does, then we want to mark that in the
+                    // event so that whoever is receiving it will know to wait for the running event and reflect
+                    // that state appropriately.
+                    // We also need to stop processing actions, since they aren't expecting the target to be running.
+                    
+                    // FIXME: we might have run.
+                    if (stop_info_sp->HasTargetRunSinceMe())
+                    {
+                        SetRestarted (true);
+                        break;
+                    }
+                    
+                    this_thread_wants_to_stop = stop_info_sp->ShouldStop(event_ptr);
                 }
                 
-                bool this_thread_wants_to_stop = stop_info_sp->ShouldStop(event_ptr);
                 if (still_should_stop == false)
                     still_should_stop = this_thread_wants_to_stop;
             }
@@ -3954,7 +4000,7 @@ Process::ProcessEventData::DoOnRemoval (
                 SetRestarted(true);
                 // Use the public resume method here, since this is just
                 // extending a public resume.
-                m_process_sp->Resume();
+                m_process_sp->PrivateResume();
             }
             else
             {
@@ -3965,7 +4011,6 @@ Process::ProcessEventData::DoOnRemoval (
                     SetRestarted(true);
             }
         }
-        
     }
 }
 
@@ -4028,6 +4073,34 @@ Process::ProcessEventData::SetRestartedI
         data->SetRestarted(new_value);
 }
 
+size_t
+Process::ProcessEventData::GetNumRestartedReasons(const Event *event_ptr)
+{
+    ProcessEventData *data = const_cast<ProcessEventData *>(GetEventDataFromEvent (event_ptr));
+    if (data != NULL)
+        return data->GetNumRestartedReasons();
+    else
+        return 0;
+}
+
+const char *
+Process::ProcessEventData::GetRestartedReasonAtIndex(const Event *event_ptr, size_t idx)
+{
+    ProcessEventData *data = const_cast<ProcessEventData *>(GetEventDataFromEvent (event_ptr));
+    if (data != NULL)
+        return data->GetRestartedReasonAtIndex(idx);
+    else
+        return NULL;
+}
+
+void
+Process::ProcessEventData::AddRestartedReason (Event *event_ptr, const char *reason)
+{
+    ProcessEventData *data = const_cast<ProcessEventData *>(GetEventDataFromEvent (event_ptr));
+    if (data != NULL)
+        data->AddRestartedReason(reason);
+}
+
 bool
 Process::ProcessEventData::GetInterruptedFromEvent (const Event *event_ptr)
 {
@@ -4479,12 +4552,38 @@ Process::RunThreadPlan (ExecutionContext
         TimeValue* timeout_ptr = NULL;
         TimeValue real_timeout;
         
-        bool first_timeout = true;
+        bool before_first_timeout = true;  // This is set to false the first time that we have to halt the target.
         bool do_resume = true;
         bool handle_running_event = true;
         const uint64_t default_one_thread_timeout_usec = 250000;
-        uint64_t computed_timeout = 0;
         
+        // This is just for accounting:
+        uint32_t num_resumes = 0;
+        
+        TimeValue one_thread_timeout = TimeValue::Now();
+        TimeValue final_timeout = one_thread_timeout;
+        
+        if (run_others)
+        {
+            // If we are running all threads then we take half the time to run all threads, bounded by
+            // .25 sec.
+            if (timeout_usec == 0)
+                one_thread_timeout.OffsetWithMicroSeconds(default_one_thread_timeout_usec);
+            else
+            {
+                uint64_t computed_timeout = computed_timeout = timeout_usec / 2;
+                if (computed_timeout > default_one_thread_timeout_usec)
+                    computed_timeout = default_one_thread_timeout_usec;
+                one_thread_timeout.OffsetWithMicroSeconds(computed_timeout);
+            }
+            final_timeout.OffsetWithMicroSeconds (timeout_usec);
+        }
+        else
+        {
+            if (timeout_usec != 0)
+                final_timeout.OffsetWithMicroSeconds(timeout_usec);
+        }
+
         // This while loop must exit out the bottom, there's cleanup that we need to do when we are done.
         // So don't call return anywhere within it.
         
@@ -4493,6 +4592,11 @@ Process::RunThreadPlan (ExecutionContext
             // We usually want to resume the process if we get to the top of the loop.
             // The only exception is if we get two running events with no intervening
             // stop, which can happen, we will just wait for then next stop event.
+            if (log)
+                log->Printf ("Top of while loop: do_resume: %i handle_running_event: %i before_first_timeout: %i.",
+                             do_resume,
+                             handle_running_event,
+                             before_first_timeout);
             
             if (do_resume || handle_running_event)
             {
@@ -4500,38 +4604,59 @@ Process::RunThreadPlan (ExecutionContext
         
                 if (do_resume)
                 {
+                    num_resumes++;
                     Error resume_error = PrivateResume ();
                     if (!resume_error.Success())
                     {
-                        errors.Printf("Error resuming inferior: \"%s\".\n", resume_error.AsCString());
+                        errors.Printf("Error resuming inferior the %d time: \"%s\".\n",
+                                      num_resumes,
+                                      resume_error.AsCString());
                         return_value = eExecutionSetupError;
                         break;
                     }
                 }
-        
-                real_timeout = TimeValue::Now();
-                real_timeout.OffsetWithMicroSeconds(500000);
-                timeout_ptr = &real_timeout;
                 
-                got_event = listener.WaitForEvent(timeout_ptr, event_sp);
+                TimeValue resume_timeout = TimeValue::Now();
+                resume_timeout.OffsetWithMicroSeconds(500000);
+                
+                got_event = listener.WaitForEvent(&resume_timeout, event_sp);
                 if (!got_event)
                 {
                     if (log)
-                        log->PutCString("Process::RunThreadPlan(): didn't get any event after initial resume, exiting.");
+                        log->Printf ("Process::RunThreadPlan(): didn't get any event after resume %d, exiting.",
+                                        num_resumes);
 
-                    errors.Printf("Didn't get any event after initial resume, exiting.");
+                    errors.Printf("Didn't get any event after resume %d, exiting.", num_resumes);
                     return_value = eExecutionSetupError;
                     break;
                 }
                 
                 stop_state = Process::ProcessEventData::GetStateFromEvent(event_sp.get());
+
                 if (stop_state != eStateRunning)
                 {
-                    if (log)
-                        log->Printf("Process::RunThreadPlan(): didn't get running event after "
-                                    "initial resume, got %s instead.",
-                                    StateAsCString(stop_state));
-
+                    bool restarted = false;
+                    
+                    if (stop_state == eStateStopped)
+                    {
+                        restarted = Process::ProcessEventData::GetRestartedFromEvent(event_sp.get());
+                        if (log)
+                            log->Printf("Process::RunThreadPlan(): didn't get running event after "
+                                        "resume %d, got %s instead (restarted: %i, do_resume: %i, handle_running_event: %i).",
+                                        num_resumes,
+                                        StateAsCString(stop_state),
+                                        restarted,
+                                        do_resume,
+                                        handle_running_event);
+                    }
+                    
+                    if (restarted)
+                    {
+                        // This is probably an overabundance of caution, I don't think I should ever get a stopped & restarted
+                        // event here.  But if I do, the best thing is to Halt and then get out of here.
+                        Halt();
+                    }
+                    
                     errors.Printf("Didn't get running event after initial resume, got %s instead.",
                                   StateAsCString(stop_state));
                     return_value = eExecutionSetupError;
@@ -4545,55 +4670,35 @@ Process::RunThreadPlan (ExecutionContext
                 // won't be able to gather the result at this point.
                 // We set the timeout AFTER the resume, since the resume takes some time and we
                 // don't want to charge that to the timeout.
-                
-                if (first_timeout)
-                {
-                    if (run_others)
-                    {
-                        // If we are running all threads then we take half the time to run all threads, bounded by
-                        // .25 sec.
-                        if (timeout_usec == 0)
-                            computed_timeout = default_one_thread_timeout_usec;
-                        else
-                        {
-                            computed_timeout = timeout_usec / 2;
-                            if (computed_timeout > default_one_thread_timeout_usec)
-                            {
-                                computed_timeout = default_one_thread_timeout_usec;
-                            }
-                            timeout_usec -= computed_timeout;
-                        }
-                    }
-                    else
-                    {
-                        computed_timeout = timeout_usec;
-                    }
-                }
-                else
-                {
-                    computed_timeout = timeout_usec;
-                }
-                
-                if (computed_timeout != 0)
-                {
-                    // we have a > 0 timeout, let us set it so that we stop after the deadline
-                    real_timeout = TimeValue::Now();
-                    real_timeout.OffsetWithMicroSeconds(computed_timeout);
+            }
+            else
+            {
+                if (log)
+                    log->PutCString ("Process::RunThreadPlan(): waiting for next event.");
+            }
                         
-                    timeout_ptr = &real_timeout;
-                }
+            if (before_first_timeout)
+            {
+                if (run_others)
+                    timeout_ptr = &one_thread_timeout;
                 else
                 {
-                    timeout_ptr = NULL;
+                    if (timeout_usec == 0)
+                        timeout_ptr = NULL;
+                    else
+                        timeout_ptr = &final_timeout;
                 }
             }
             else
             {
-                if (log)
-                    log->PutCString ("Process::RunThreadPlan(): handled an extra running event.");
-                do_resume = true;
-                handle_running_event = true;
+                if (timeout_usec == 0)
+                    timeout_ptr = NULL;
+                else
+                    timeout_ptr = &final_timeout;
             }
+        
+            do_resume = true;
+            handle_running_event = true;
             
             // Now wait for the process to stop again:
             event_sp.reset();
@@ -4602,12 +4707,9 @@ Process::RunThreadPlan (ExecutionContext
             {
                 if (timeout_ptr)
                 {
-                    StreamString s;
-                    s.Printf ("about to wait - timeout is:\n   ");
-                    timeout_ptr->Dump (&s, 120);
-                    s.Printf ("\nNow is:\n    ");
-                    TimeValue::Now().Dump (&s, 120);
-                    log->Printf ("Process::RunThreadPlan(): %s", s.GetData());
+                    log->Printf ("Process::RunThreadPlan(): about to wait - now is %llu - endpoint is %llu",
+                                 TimeValue::Now().GetAsMicroSecondsSinceJan1_1970(),
+                                 timeout_ptr->GetAsMicroSecondsSinceJan1_1970());
                 }
                 else
                 {
@@ -4625,11 +4727,11 @@ Process::RunThreadPlan (ExecutionContext
                     if (event_sp->GetType() == eBroadcastBitInterrupt)
                     {
                         Halt();
-                        keep_going = false;
                         return_value = eExecutionInterrupted;
                         errors.Printf ("Execution halted by user interrupt.");
                         if (log)
                             log->Printf ("Process::RunThreadPlan(): Got  interrupted by eBroadcastBitInterrupted, exiting.");
+                        break;
                     }
                     else
                     {
@@ -4641,7 +4743,7 @@ Process::RunThreadPlan (ExecutionContext
                         {
                         case lldb::eStateStopped:
                             {
-                                // Yay, we're done.  Now make sure that our thread plan actually completed.
+                                // We stopped, figure out what we are going to do now.
                                 ThreadSP thread_sp = GetThreadList().FindThreadByIndexID (thread_idx_id);
                                 if (!thread_sp)
                                 {
@@ -4652,52 +4754,63 @@ Process::RunThreadPlan (ExecutionContext
                                 }
                                 else
                                 {
-                                    StopInfoSP stop_info_sp (thread_sp->GetStopInfo ());
-                                    StopReason stop_reason = eStopReasonInvalid;
-                                    if (stop_info_sp)
-                                         stop_reason = stop_info_sp->GetStopReason();
-                                    if (stop_reason == eStopReasonPlanComplete)
+                                    // If we were restarted, we just need to go back up to fetch another event.
+                                    if (Process::ProcessEventData::GetRestartedFromEvent(event_sp.get()))
                                     {
                                         if (log)
-                                            log->PutCString ("Process::RunThreadPlan(): execution completed successfully.");
-                                        // Now mark this plan as private so it doesn't get reported as the stop reason
-                                        // after this point.  
-                                        if (thread_plan_sp)
-                                            thread_plan_sp->SetPrivate (orig_plan_private);
-                                        return_value = eExecutionCompleted;
+                                        {
+                                            log->Printf ("Process::RunThreadPlan(): Got a stop and restart, so we'll continue waiting.");
+                                        }
+                                       keep_going = true;
+                                       do_resume = false;
+                                       handle_running_event = true;
+                                       
                                     }
                                     else
                                     {
-                                        // Something restarted the target, so just wait for it to stop for real.
-                                        if (Process::ProcessEventData::GetRestartedFromEvent(event_sp.get()))
+                                    
+                                        StopInfoSP stop_info_sp (thread_sp->GetStopInfo ());
+                                        StopReason stop_reason = eStopReasonInvalid;
+                                        if (stop_info_sp)
+                                             stop_reason = stop_info_sp->GetStopReason();
+                                        
+                                        
+                                        // FIXME: We only check if the stop reason is plan complete, should we make sure that
+                                        // it is OUR plan that is complete?
+                                        if (stop_reason == eStopReasonPlanComplete)
                                         {
                                             if (log)
-                                                log->PutCString ("Process::RunThreadPlan(): Somebody stopped and then restarted, we'll continue waiting.");
-                                           keep_going = true;
-                                           do_resume = false;
-                                           handle_running_event = true;
+                                                log->PutCString ("Process::RunThreadPlan(): execution completed successfully.");
+                                            // Now mark this plan as private so it doesn't get reported as the stop reason
+                                            // after this point.  
+                                            if (thread_plan_sp)
+                                                thread_plan_sp->SetPrivate (orig_plan_private);
+                                            return_value = eExecutionCompleted;
                                         }
                                         else
                                         {
-                                            if (log)
-                                                log->PutCString ("Process::RunThreadPlan(): thread plan didn't successfully complete.");
+                                            // Something restarted the target, so just wait for it to stop for real.
                                             if (stop_reason == eStopReasonBreakpoint)
+                                            {
+                                                if (log)
+                                                    log->Printf ("Process::RunThreadPlan() stopped for breakpoint: %s.", stop_info_sp->GetDescription());
                                                 return_value = eExecutionHitBreakpoint;
+                                            }
                                             else
+                                            {
+                                                if (log)
+                                                    log->PutCString ("Process::RunThreadPlan(): thread plan didn't successfully complete.");
                                                 return_value = eExecutionInterrupted;
+                                            }
                                         }
                                     }
                                 }
                             }        
                             break;
 
-                        case lldb::eStateCrashed:
-                            if (log)
-                                log->PutCString ("Process::RunThreadPlan(): execution crashed.");
-                            return_value = eExecutionInterrupted;
-                            break;
-
                         case lldb::eStateRunning:
+                            // This shouldn't really happen, but sometimes we do get two running events without an
+                            // intervening stop, and in that case we should just go back to waiting for the stop.
                             do_resume = false;
                             keep_going = true;
                             handle_running_event = false;
@@ -4734,15 +4847,15 @@ Process::RunThreadPlan (ExecutionContext
                 // If we didn't get an event that means we've timed out...
                 // We will interrupt the process here.  Depending on what we were asked to do we will
                 // either exit, or try with all threads running for the same timeout.
-                // Not really sure what to do if Halt fails here...
                 
                 if (log) {
                     if (run_others)
                     {
-                        if (first_timeout)
-                            log->Printf ("Process::RunThreadPlan(): Running function with timeout: %" PRId64 " timed out, "
-                                         "trying  for %d usec with all threads enabled.",
-                                         computed_timeout, timeout_usec);
+                        uint64_t remaining_time = final_timeout - TimeValue::Now();
+                        if (before_first_timeout)
+                            log->Printf ("Process::RunThreadPlan(): Running function with one thread timeout timed out, "
+                                         "running till  for %" PRId64 " usec with all threads enabled.",
+                                         remaining_time);
                         else
                             log->Printf ("Process::RunThreadPlan(): Restarting function with all threads enabled "
                                          "and timeout: %d timed out, abandoning execution.",
@@ -4754,148 +4867,122 @@ Process::RunThreadPlan (ExecutionContext
                                      timeout_usec);
                 }
                 
-                Error halt_error = Halt();
-                if (halt_error.Success())
-                {
-                    if (log)
-                        log->PutCString ("Process::RunThreadPlan(): Halt succeeded.");
-                        
-                    // If halt succeeds, it always produces a stopped event.  Wait for that:
-                    
-                    real_timeout = TimeValue::Now();
-                    real_timeout.OffsetWithMicroSeconds(500000);
-
-                    got_event = listener.WaitForEvent(&real_timeout, event_sp);
-                    
-                    if (got_event)
-                    {
-                        stop_state = Process::ProcessEventData::GetStateFromEvent(event_sp.get());
-                        if (log)
-                        {
-                            log->Printf ("Process::RunThreadPlan(): Stopped with event: %s", StateAsCString(stop_state));
-                            if (stop_state == lldb::eStateStopped 
-                                && Process::ProcessEventData::GetInterruptedFromEvent(event_sp.get()))
-                                log->PutCString ("    Event was the Halt interruption event.");
-                        }
-                        
-                        if (stop_state == lldb::eStateStopped)
-                        {
-                            // Between the time we initiated the Halt and the time we delivered it, the process could have
-                            // already finished its job.  Check that here:
-                            
-                            if (thread->IsThreadPlanDone (thread_plan_sp.get()))
-                            {
-                                if (log)
-                                    log->PutCString ("Process::RunThreadPlan(): Even though we timed out, the call plan was done.  "
-                                                 "Exiting wait loop.");
-                                return_value = eExecutionCompleted;
-                                break;
-                            }
-
-                            if (!run_others)
-                            {
-                                if (log)
-                                    log->PutCString ("Process::RunThreadPlan(): try_all_threads was false, we stopped so now we're quitting.");
-                                return_value = eExecutionInterrupted;
-                                break;
-                            }
-                            
-                            if (first_timeout)
-                            {
-                                // Set all the other threads to run, and return to the top of the loop, which will continue;
-                                first_timeout = false;
-                                thread_plan_sp->SetStopOthers (false);
-                                if (log)
-                                    log->PutCString ("Process::RunThreadPlan(): about to resume.");
-
-                                continue;
-                            }
-                            else
-                            {
-                                // Running all threads failed, so return Interrupted.
-                                if (log)
-                                    log->PutCString("Process::RunThreadPlan(): running all threads timed out.");
-                                return_value = eExecutionInterrupted;
-                                break;
-                            }
-                        }
-                    }
-                    else
-                    {   if (log)
-                            log->PutCString("Process::RunThreadPlan(): halt said it succeeded, but I got no event.  "
-                                    "I'm getting out of here passing Interrupted.");
-                        return_value = eExecutionInterrupted;
-                        break;
-                    }
-                }
-                else
+                // It is possible that between the time we issued the Halt, and we get around to calling Halt the target
+                // could have stopped.  That's fine, Halt will figure that out and send the appropriate Stopped event.
+                // BUT it is also possible that we stopped & restarted (e.g. hit a signal with "stop" set to false.)  In
+                // that case, we'll get the stopped & restarted event, and we should go back to waiting for the Halt's
+                // stopped event.  That's what this while loop does.
+                
+                bool back_to_top = true;
+                uint32_t try_halt_again = 0;
+                bool do_halt = true;
+                const uint32_t num_retries = 5;
+                while (try_halt_again < num_retries)
                 {
-                    // This branch is to work around some problems with gdb-remote's Halt.  It is a little racy, and can return 
-                    // an error from halt, but if you wait a bit you'll get a stopped event anyway.
-                    if (log)
-                        log->Printf ("Process::RunThreadPlan(): halt failed: error = \"%s\", I'm just going to wait a little longer and see if I get a stopped event.", 
-                                     halt_error.AsCString());                
-                    real_timeout = TimeValue::Now();
-                    real_timeout.OffsetWithMicroSeconds(500000);
-                    timeout_ptr = &real_timeout;
-                    got_event = listener.WaitForEvent(&real_timeout, event_sp);
-                    if (!got_event || event_sp.get() == NULL)
+                    Error halt_error;
+                    if (do_halt)
                     {
-                        // This is not going anywhere, bag out.
                         if (log)
-                            log->PutCString ("Process::RunThreadPlan(): halt failed: and waiting for the stopped event failed.");
-                        return_value = eExecutionInterrupted;
-                        break;                
+                            log->Printf ("Process::RunThreadPlan(): Running Halt.");
+                        halt_error = Halt();
                     }
-                    else
+                    if (halt_error.Success())
                     {
-                        stop_state = Process::ProcessEventData::GetStateFromEvent(event_sp.get());
                         if (log)
-                            log->PutCString ("Process::RunThreadPlan(): halt failed: but then I got a stopped event.  Whatever...");
-                        if (stop_state == lldb::eStateStopped)
-                        {
-                            // Between the time we initiated the Halt and the time we delivered it, the process could have
-                            // already finished its job.  Check that here:
+                            log->PutCString ("Process::RunThreadPlan(): Halt succeeded.");
                             
-                            if (thread->IsThreadPlanDone (thread_plan_sp.get()))
-                            {
-                                if (log)
-                                    log->PutCString ("Process::RunThreadPlan(): Even though we timed out, the call plan was done.  "
-                                                 "Exiting wait loop.");
-                                return_value = eExecutionCompleted;
-                                break;
-                            }
+                        real_timeout = TimeValue::Now();
+                        real_timeout.OffsetWithMicroSeconds(500000);
 
-                            if (first_timeout)
+                        got_event = listener.WaitForEvent(&real_timeout, event_sp);
+                        
+                        if (got_event)
+                        {
+                            stop_state = Process::ProcessEventData::GetStateFromEvent(event_sp.get());
+                            if (log)
                             {
-                                // Set all the other threads to run, and return to the top of the loop, which will continue;
-                                first_timeout = false;
-                                thread_plan_sp->SetStopOthers (false);
-                                if (log)
-                                    log->PutCString ("Process::RunThreadPlan(): About to resume.");
-
-                                continue;
+                                log->Printf ("Process::RunThreadPlan(): Stopped with event: %s", StateAsCString(stop_state));
+                                if (stop_state == lldb::eStateStopped 
+                                    && Process::ProcessEventData::GetInterruptedFromEvent(event_sp.get()))
+                                    log->PutCString ("    Event was the Halt interruption event.");
                             }
-                            else
+                            
+                            if (stop_state == lldb::eStateStopped)
                             {
-                                // Running all threads failed, so return Interrupted.
-                                if (log)
-                                    log->PutCString ("Process::RunThreadPlan(): running all threads timed out.");
-                                return_value = eExecutionInterrupted;
-                                break;
+                                // Between the time we initiated the Halt and the time we delivered it, the process could have
+                                // already finished its job.  Check that here:
+                                
+                                if (thread->IsThreadPlanDone (thread_plan_sp.get()))
+                                {
+                                    if (log)
+                                        log->PutCString ("Process::RunThreadPlan(): Even though we timed out, the call plan was done.  "
+                                                     "Exiting wait loop.");
+                                    return_value = eExecutionCompleted;
+                                    back_to_top = false;
+                                    break;
+                                }
+                                
+                                if (Process::ProcessEventData::GetRestartedFromEvent(event_sp.get()))
+                                {
+                                    if (log)
+                                        log->PutCString ("Process::RunThreadPlan(): Went to halt but got a restarted event, there must be an un-restarted stopped event so try again...  "
+                                                     "Exiting wait loop.");
+                                    try_halt_again++;
+                                    do_halt = false;
+                                    continue;
+                                }
+
+                                if (!run_others)
+                                {
+                                    if (log)
+                                        log->PutCString ("Process::RunThreadPlan(): try_all_threads was false, we stopped so now we're quitting.");
+                                    return_value = eExecutionInterrupted;
+                                    back_to_top = false;
+                                    break;
+                                }
+                                
+                                if (before_first_timeout)
+                                {
+                                    // Set all the other threads to run, and return to the top of the loop, which will continue;
+                                    before_first_timeout = false;
+                                    thread_plan_sp->SetStopOthers (false);
+                                    if (log)
+                                        log->PutCString ("Process::RunThreadPlan(): about to resume.");
+
+                                    back_to_top = true;
+                                    break;
+                                }
+                                else
+                                {
+                                    // Running all threads failed, so return Interrupted.
+                                    if (log)
+                                        log->PutCString("Process::RunThreadPlan(): running all threads timed out.");
+                                    return_value = eExecutionInterrupted;
+                                    back_to_top = false;
+                                    break;
+                                }
                             }
                         }
                         else
-                        {
-                            if (log)
-                                log->Printf ("Process::RunThreadPlan(): halt failed, I waited and didn't get"
-                                             " a stopped event, instead got %s.", StateAsCString(stop_state));
+                        {   if (log)
+                                log->PutCString("Process::RunThreadPlan(): halt said it succeeded, but I got no event.  "
+                                        "I'm getting out of here passing Interrupted.");
                             return_value = eExecutionInterrupted;
-                            break;                
+                            back_to_top = false;
+                            break;
                         }
                     }
+                    else
+                    {
+                        try_halt_again++;
+                        continue;
+                    }
                 }
-
+                
+                if (!back_to_top || try_halt_again > num_retries)
+                    break;
+                else
+                    continue;
             }
         }  // END WAIT LOOP
         

Modified: lldb/trunk/source/Target/StopInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/StopInfo.cpp?rev=174793&r1=174792&r2=174793&view=diff
==============================================================================
--- lldb/trunk/source/Target/StopInfo.cpp (original)
+++ lldb/trunk/source/Target/StopInfo.cpp Fri Feb  8 19:29:05 2013
@@ -38,7 +38,9 @@ StopInfo::StopInfo (Thread &thread, uint
     m_thread (thread),
     m_stop_id (thread.GetProcess()->GetStopID()),
     m_resume_id (thread.GetProcess()->GetResumeID()),
-    m_value (value)
+    m_value (value),
+    m_override_set(false),
+    m_override_value(true)
 {
 }
 
@@ -773,6 +775,12 @@ public:
     }
 
     virtual bool
+    ShouldStopSynchronous (Event *event_ptr)
+    {
+        return m_thread.GetProcess()->GetUnixSignals().GetShouldStop (m_value);
+    }
+
+    virtual bool
     ShouldStop (Event *event_ptr)
     {
         return m_thread.GetProcess()->GetUnixSignals().GetShouldStop (m_value);
@@ -783,7 +791,16 @@ public:
     virtual bool
     ShouldNotify (Event *event_ptr)
     {
-        return m_thread.GetProcess()->GetUnixSignals().GetShouldNotify (m_value);
+        bool should_notify = m_thread.GetProcess()->GetUnixSignals().GetShouldNotify (m_value);
+        if (should_notify)
+        {
+            StreamString strm;
+            strm.Printf ("thread %d received signal: %s",
+                         m_thread.GetIndexID(),
+                         m_thread.GetProcess()->GetUnixSignals().GetSignalAsCString (m_value));
+            Process::ProcessEventData::AddRestartedReason(event_ptr, strm.GetData());
+        }
+        return should_notify;
     }
 
     
@@ -924,6 +941,16 @@ public:
     {
         return m_return_valobj_sp;
     }
+    
+protected:
+    virtual bool
+    ShouldStop (Event *event_ptr)
+    {
+        if (m_plan_sp)
+            return m_plan_sp->ShouldStop(event_ptr);
+        else
+            return StopInfo::ShouldStop(event_ptr);
+    }
 
 private:
     ThreadPlanSP m_plan_sp;
@@ -957,7 +984,6 @@ public:
         return "exec";
     }
 protected:
-protected:
     
     virtual void
     PerformAction (Event *event_ptr)

Modified: lldb/trunk/source/Target/Thread.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/Thread.cpp?rev=174793&r1=174792&r2=174793&view=diff
==============================================================================
--- lldb/trunk/source/Target/Thread.cpp (original)
+++ lldb/trunk/source/Target/Thread.cpp Fri Feb  8 19:29:05 2013
@@ -646,7 +646,7 @@ Thread::ShouldStop (Event* event_ptr)
     
     bool done_processing_current_plan = false;
     
-    if (!current_plan->PlanExplainsStop())
+    if (!current_plan->PlanExplainsStop(event_ptr))
     {
         if (current_plan->TracerExplainsStop())
         {
@@ -660,7 +660,7 @@ Thread::ShouldStop (Event* event_ptr)
             ThreadPlan *plan_ptr = current_plan;
             while ((plan_ptr = GetPreviousPlan(plan_ptr)) != NULL)
             {
-                if (plan_ptr->PlanExplainsStop())
+                if (plan_ptr->PlanExplainsStop(event_ptr))
                 {
                     should_stop = plan_ptr->ShouldStop (event_ptr);
                     
@@ -831,9 +831,24 @@ Thread::ShouldReportStop (Event* event_p
     }
     else
     {
+        Vote thread_vote = eVoteNoOpinion;
+        ThreadPlan *plan_ptr = GetCurrentPlan();
+        while (1)
+        {
+            if (plan_ptr->PlanExplainsStop(event_ptr))
+            {
+                thread_vote = plan_ptr->ShouldReportStop(event_ptr);
+                break;
+            }
+            if (PlanIsBasePlan(plan_ptr))
+                break;
+            else
+                plan_ptr = GetPreviousPlan(plan_ptr);
+        }
         if (log)
-            log->Printf ("Thread::ShouldReportStop() tid = 0x%4.4" PRIx64 ": returning vote  for current plan\n", GetID());
-        return GetCurrentPlan()->ShouldReportStop (event_ptr);
+            log->Printf ("Thread::ShouldReportStop() tid = 0x%4.4" PRIx64 ": returning vote %i for current plan\n", GetID(), thread_vote);
+
+        return thread_vote;
     }
 }
 

Modified: lldb/trunk/source/Target/ThreadPlanBase.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/ThreadPlanBase.cpp?rev=174793&r1=174792&r2=174793&view=diff
==============================================================================
--- lldb/trunk/source/Target/ThreadPlanBase.cpp (original)
+++ lldb/trunk/source/Target/ThreadPlanBase.cpp Fri Feb  8 19:29:05 2013
@@ -68,7 +68,7 @@ ThreadPlanBase::ValidatePlan (Stream *er
 }
 
 bool
-ThreadPlanBase::PlanExplainsStop ()
+ThreadPlanBase::PlanExplainsStop (Event *event_ptr)
 {
     // The base plan should defer to its tracer, since by default it
     // always handles the stop.

Modified: lldb/trunk/source/Target/ThreadPlanCallFunction.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/ThreadPlanCallFunction.cpp?rev=174793&r1=174792&r2=174793&view=diff
==============================================================================
--- lldb/trunk/source/Target/ThreadPlanCallFunction.cpp (original)
+++ lldb/trunk/source/Target/ThreadPlanCallFunction.cpp Fri Feb  8 19:29:05 2013
@@ -231,7 +231,7 @@ ThreadPlanCallFunction::ThreadPlanCallFu
 
 ThreadPlanCallFunction::~ThreadPlanCallFunction ()
 {
-    DoTakedown(true);
+    DoTakedown(PlanSucceeded());
 }
 
 void
@@ -309,7 +309,7 @@ ThreadPlanCallFunction::DoTakedown (bool
 void
 ThreadPlanCallFunction::WillPop ()
 {
-    DoTakedown(true);
+    DoTakedown(PlanSucceeded());
 }
 
 void
@@ -335,14 +335,25 @@ ThreadPlanCallFunction::ValidatePlan (St
     return true;
 }
 
+
+Vote
+ThreadPlanCallFunction::ShouldReportStop(Event *event_ptr)
+{
+    if (m_takedown_done || IsPlanComplete())
+        return eVoteYes;
+    else
+        return ThreadPlan::ShouldReportStop(event_ptr);
+}
+
 bool
-ThreadPlanCallFunction::PlanExplainsStop ()
+ThreadPlanCallFunction::PlanExplainsStop (Event *event_ptr)
 {    
+    LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_STEP|LIBLLDB_LOG_PROCESS));
     m_real_stop_info_sp = GetPrivateStopReason();
     
     // If our subplan knows why we stopped, even if it's done (which would forward the question to us)
     // we answer yes.
-    if (m_subplan_sp.get() != NULL && m_subplan_sp->PlanExplainsStop())
+    if (m_subplan_sp.get() != NULL && m_subplan_sp->PlanExplainsStop(event_ptr))
     {
         SetPlanComplete();
         return true;
@@ -355,16 +366,15 @@ ThreadPlanCallFunction::PlanExplainsStop
         stop_reason = eStopReasonNone;
     else
         stop_reason = m_real_stop_info_sp->GetStopReason();
+    if (log)
+        log->Printf ("ThreadPlanCallFunction::PlanExplainsStop: Got stop reason - %s.", Thread::StopReasonAsCString(stop_reason));
 
     if (stop_reason == eStopReasonBreakpoint && BreakpointsExplainStop())
         return true;
     
-    // If we don't want to discard this plan, than any stop we don't understand should be propagated up the stack.
-    if (!m_unwind_on_error)
-        return false;
-            
-    // Otherwise, check the case where we stopped for an internal breakpoint, in that case, continue on.
-    // If it is not an internal breakpoint, consult OkayToDiscard.
+    // We control breakpoints separately from other "stop reasons."  So first,
+    // check the case where we stopped for an internal breakpoint, in that case, continue on.
+    // If it is not an internal breakpoint, consult m_ignore_breakpoints.
     
     
     if (stop_reason == eStopReasonBreakpoint)
@@ -381,6 +391,8 @@ ThreadPlanCallFunction::PlanExplainsStop
             for (uint32_t i = 0; i < num_owners; i++)
             {
                 Breakpoint &bp = bp_site_sp->GetOwnerAtIndex(i)->GetBreakpoint();
+                if (log)
+                    log->Printf ("ThreadPlanCallFunction::PlanExplainsStop: hit breakpoint %d while calling function", bp.GetID());
                 
                 if (!bp.IsInternal())
                 {
@@ -389,16 +401,32 @@ ThreadPlanCallFunction::PlanExplainsStop
                 }
             }
             if (is_internal)
+            {
+                if (log)
+                    log->Printf ("ThreadPlanCallFunction::PlanExplainsStop hit an internal breakpoint, not stopping.");
                 return false;
+            }
         }
-        
+
         if (m_ignore_breakpoints)
         {
-            DoTakedown(false);
+            if (log)
+                log->Printf("ThreadPlanCallFunction::PlanExplainsStop: we are ignoring breakpoints, overriding breakpoint stop info ShouldStop, returning true");
+            m_real_stop_info_sp->OverrideShouldStop(false);
             return true;
         }
         else
+        {
+            if (log)
+                log->Printf("ThreadPlanCallFunction::PlanExplainsStop: we are not ignoring breakpoints, overriding breakpoint stop info ShouldStop, returning true");
+            m_real_stop_info_sp->OverrideShouldStop(true);
             return false;
+        }
+    }
+    else if (!m_unwind_on_error)
+    {
+        // If we don't want to discard this plan, than any stop we don't understand should be propagated up the stack.
+        return false;
     }
     else
     {
@@ -406,19 +434,25 @@ ThreadPlanCallFunction::PlanExplainsStop
         // If we want to discard the plan, then we say we explain the stop
         // but if we are going to be discarded, let whoever is above us
         // explain the stop.
-        SetPlanComplete(false);
-        if (m_subplan_sp)
+        // But don't discard the plan if the stop would restart itself (for instance if it is a
+        // signal that is set not to stop.  Check that here first.  We just say we explain the stop
+        // but aren't done and everything will continue on from there.
+        
+        if (m_real_stop_info_sp->ShouldStopSynchronous(event_ptr))
         {
-            if (m_unwind_on_error)
+            SetPlanComplete(false);
+            if (m_subplan_sp)
             {
-                DoTakedown(false);
-                return true;
+                if (m_unwind_on_error)
+                    return true;
+                else
+                    return false;
             }
             else
                 return false;
         }
         else
-            return false;
+            return true;
     }
 }
 
@@ -427,14 +461,11 @@ ThreadPlanCallFunction::ShouldStop (Even
 {
     // We do some computation in PlanExplainsStop that may or may not set the plan as complete.
     // We need to do that here to make sure our state is correct.
-    PlanExplainsStop();
+    PlanExplainsStop(event_ptr);
     
     if (IsPlanComplete())
     {
         ReportRegisterState ("Function completed.  Register state was:");
-        
-        DoTakedown(true);
-        
         return true;
     }
     else
@@ -495,12 +526,6 @@ ThreadPlanCallFunction::MischiefManaged
 {
     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
     
-    if (PlanExplainsStop() && !IsPlanComplete())
-    {
-        if (log)
-            log->Printf ("ThreadPlanCallFunction: Got into MischiefManaged, explained stop but was not complete.");
-    }
-    
     if (IsPlanComplete())
     {
         if (log)

Modified: lldb/trunk/source/Target/ThreadPlanRunToAddress.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/ThreadPlanRunToAddress.cpp?rev=174793&r1=174792&r2=174793&view=diff
==============================================================================
--- lldb/trunk/source/Target/ThreadPlanRunToAddress.cpp (original)
+++ lldb/trunk/source/Target/ThreadPlanRunToAddress.cpp Fri Feb  8 19:29:05 2013
@@ -188,7 +188,7 @@ ThreadPlanRunToAddress::ValidatePlan (St
 }
 
 bool
-ThreadPlanRunToAddress::PlanExplainsStop ()
+ThreadPlanRunToAddress::PlanExplainsStop (Event *event_ptr)
 {
     return AtOurAddress();
 }

Modified: lldb/trunk/source/Target/ThreadPlanStepInRange.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/ThreadPlanStepInRange.cpp?rev=174793&r1=174792&r2=174793&view=diff
==============================================================================
--- lldb/trunk/source/Target/ThreadPlanStepInRange.cpp (original)
+++ lldb/trunk/source/Target/ThreadPlanStepInRange.cpp Fri Feb  8 19:29:05 2013
@@ -351,7 +351,7 @@ ThreadPlanStepInRange::DefaultShouldStop
 }
 
 bool
-ThreadPlanStepInRange::PlanExplainsStop ()
+ThreadPlanStepInRange::PlanExplainsStop (Event *event_ptr)
 {
     // We always explain a stop.  Either we've just done a single step, in which
     // case we'll do our ordinary processing, or we stopped for some

Modified: lldb/trunk/source/Target/ThreadPlanStepInstruction.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/ThreadPlanStepInstruction.cpp?rev=174793&r1=174792&r2=174793&view=diff
==============================================================================
--- lldb/trunk/source/Target/ThreadPlanStepInstruction.cpp (original)
+++ lldb/trunk/source/Target/ThreadPlanStepInstruction.cpp Fri Feb  8 19:29:05 2013
@@ -81,7 +81,7 @@ ThreadPlanStepInstruction::ValidatePlan
 }
 
 bool
-ThreadPlanStepInstruction::PlanExplainsStop ()
+ThreadPlanStepInstruction::PlanExplainsStop (Event *event_ptr)
 {
     StopInfoSP stop_info_sp = GetPrivateStopReason();
     if (stop_info_sp)

Modified: lldb/trunk/source/Target/ThreadPlanStepOut.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/ThreadPlanStepOut.cpp?rev=174793&r1=174792&r2=174793&view=diff
==============================================================================
--- lldb/trunk/source/Target/ThreadPlanStepOut.cpp (original)
+++ lldb/trunk/source/Target/ThreadPlanStepOut.cpp Fri Feb  8 19:29:05 2013
@@ -174,7 +174,7 @@ ThreadPlanStepOut::ValidatePlan (Stream
 }
 
 bool
-ThreadPlanStepOut::PlanExplainsStop ()
+ThreadPlanStepOut::PlanExplainsStop (Event *event_ptr)
 {
     // If one of our child plans just finished, then we do explain the stop.
     if (m_step_out_plan_sp)

Modified: lldb/trunk/source/Target/ThreadPlanStepOverBreakpoint.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/ThreadPlanStepOverBreakpoint.cpp?rev=174793&r1=174792&r2=174793&view=diff
==============================================================================
--- lldb/trunk/source/Target/ThreadPlanStepOverBreakpoint.cpp (original)
+++ lldb/trunk/source/Target/ThreadPlanStepOverBreakpoint.cpp Fri Feb  8 19:29:05 2013
@@ -58,7 +58,7 @@ ThreadPlanStepOverBreakpoint::ValidatePl
 }
 
 bool
-ThreadPlanStepOverBreakpoint::PlanExplainsStop ()
+ThreadPlanStepOverBreakpoint::PlanExplainsStop (Event *event_ptr)
 {
     StopInfoSP stop_info_sp = GetPrivateStopReason();
     if (stop_info_sp)

Modified: lldb/trunk/source/Target/ThreadPlanStepOverRange.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/ThreadPlanStepOverRange.cpp?rev=174793&r1=174792&r2=174793&view=diff
==============================================================================
--- lldb/trunk/source/Target/ThreadPlanStepOverRange.cpp (original)
+++ lldb/trunk/source/Target/ThreadPlanStepOverRange.cpp Fri Feb  8 19:29:05 2013
@@ -290,7 +290,7 @@ ThreadPlanStepOverRange::ShouldStop (Eve
 }
 
 bool
-ThreadPlanStepOverRange::PlanExplainsStop ()
+ThreadPlanStepOverRange::PlanExplainsStop (Event *event_ptr)
 {
     // For crashes, breakpoint hits, signals, etc, let the base plan (or some plan above us)
     // handle the stop.  That way the user can see the stop, step around, and then when they

Modified: lldb/trunk/source/Target/ThreadPlanStepThrough.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/ThreadPlanStepThrough.cpp?rev=174793&r1=174792&r2=174793&view=diff
==============================================================================
--- lldb/trunk/source/Target/ThreadPlanStepThrough.cpp (original)
+++ lldb/trunk/source/Target/ThreadPlanStepThrough.cpp Fri Feb  8 19:29:05 2013
@@ -139,7 +139,7 @@ ThreadPlanStepThrough::ValidatePlan (Str
 }
 
 bool
-ThreadPlanStepThrough::PlanExplainsStop ()
+ThreadPlanStepThrough::PlanExplainsStop (Event *event_ptr)
 {
     // If we have a sub-plan, it will have been asked first if we explain the stop, and
     // we won't get asked.  The only time we would be the one directly asked this question

Modified: lldb/trunk/source/Target/ThreadPlanStepUntil.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/ThreadPlanStepUntil.cpp?rev=174793&r1=174792&r2=174793&view=diff
==============================================================================
--- lldb/trunk/source/Target/ThreadPlanStepUntil.cpp (original)
+++ lldb/trunk/source/Target/ThreadPlanStepUntil.cpp Fri Feb  8 19:29:05 2013
@@ -305,7 +305,7 @@ ThreadPlanStepUntil::AnalyzeStop()
 }
 
 bool
-ThreadPlanStepUntil::PlanExplainsStop ()
+ThreadPlanStepUntil::PlanExplainsStop (Event *event_ptr)
 {
     // We don't explain signals or breakpoints (breakpoints that handle stepping in or
     // out will be handled by a child plan.

Modified: lldb/trunk/test/functionalities/conditional_break/conditional_break.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/conditional_break/conditional_break.py?rev=174793&r1=174792&r2=174793&view=diff
==============================================================================
--- lldb/trunk/test/functionalities/conditional_break/conditional_break.py (original)
+++ lldb/trunk/test/functionalities/conditional_break/conditional_break.py Fri Feb  8 19:29:05 2013
@@ -32,6 +32,7 @@ def stop_if_called_from_a():
             should_stop = False
 
     dbg.SetAsync(old_async)
+    print >> sys.stdout, "stop_if_called_from_a returning: ", should_stop
     return should_stop
 
 

Modified: lldb/trunk/tools/driver/Driver.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/driver/Driver.cpp?rev=174793&r1=174792&r2=174793&view=diff
==============================================================================
--- lldb/trunk/tools/driver/Driver.cpp (original)
+++ lldb/trunk/tools/driver/Driver.cpp Fri Feb  8 19:29:05 2013
@@ -973,11 +973,32 @@ Driver::HandleProcessEvent (const SBEven
             // Make sure the program hasn't been auto-restarted:
             if (SBProcess::GetRestartedFromEvent (event))
             {
+                size_t num_reasons = SBProcess::GetNumRestartedReasonsFromEvent(event);
+                if (num_reasons > 0)
+                {
                 // FIXME: Do we want to report this, or would that just be annoyingly chatty?
-                char message[1024];
-                int message_len = ::snprintf (message, sizeof(message), "Process %" PRIu64 " stopped and was programmatically restarted.\n",
+                    if (num_reasons == 1)
+                    {
+                        char message[1024];
+                        const char *reason = SBProcess::GetRestartedReasonAtIndexFromEvent (event, 0);
+                        int message_len = ::snprintf (message, sizeof(message), "Process %" PRIu64 " stopped and restarted: %s\n",
+                                              process.GetProcessID(), reason ? reason : "<UNKNOWN REASON>");
+                        m_io_channel_ap->OutWrite(message, message_len, ASYNC);
+                    }
+                    else
+                    {
+                        char message[1024];
+                        int message_len = ::snprintf (message, sizeof(message), "Process %" PRIu64 " stopped and restarted, reasons:\n",
                                               process.GetProcessID());
-                m_io_channel_ap->OutWrite(message, message_len, ASYNC);
+                        m_io_channel_ap->OutWrite(message, message_len, ASYNC);
+                        for (size_t i = 0; i < num_reasons; i++)
+                        {
+                            const char *reason = SBProcess::GetRestartedReasonAtIndexFromEvent (event, i);
+                            int message_len = ::snprintf(message, sizeof(message), "\t%s\n", reason ? reason : "<UNKNOWN REASON>");
+                            m_io_channel_ap->OutWrite(message, message_len, ASYNC);
+                        }
+                    }
+                }
             }
             else
             {





More information about the lldb-commits mailing list