[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