summaryrefslogtreecommitdiffstats
path: root/lldb/source/Target/Thread.cpp
diff options
context:
space:
mode:
authorJim Ingham <jingham@apple.com>2010-11-11 19:26:09 +0000
committerJim Ingham <jingham@apple.com>2010-11-11 19:26:09 +0000
commit06e827cc437f0a9bfa25e201fe4e23630f2d8056 (patch)
tree91e8bc5113d757b83212b9a7807eafa09ca88841 /lldb/source/Target/Thread.cpp
parente6283f950d061c27469199cc8e9521bbef37abcd (diff)
downloadbcm5719-llvm-06e827cc437f0a9bfa25e201fe4e23630f2d8056.tar.gz
bcm5719-llvm-06e827cc437f0a9bfa25e201fe4e23630f2d8056.zip
Add ThreadPlanTracer class to allow instruction step tracing of execution.
Also changed eSetVarTypeBool to eSetVarTypeBoolean to make it consistent with eArgTypeBoolean. llvm-svn: 118824
Diffstat (limited to 'lldb/source/Target/Thread.cpp')
-rw-r--r--lldb/source/Target/Thread.cpp166
1 files changed, 118 insertions, 48 deletions
diff --git a/lldb/source/Target/Thread.cpp b/lldb/source/Target/Thread.cpp
index 4f7ff1d13e2..80434cf33f2 100644
--- a/lldb/source/Target/Thread.cpp
+++ b/lldb/source/Target/Thread.cpp
@@ -227,6 +227,9 @@ Thread::ShouldStop (Event* event_ptr)
DumpThreadPlans(&s);
log->PutCString (s.GetData());
}
+
+ // The top most plan always gets to do the trace log...
+ current_plan->DoTraceLog ();
if (current_plan->PlanExplainsStop())
{
@@ -268,6 +271,10 @@ Thread::ShouldStop (Event* event_ptr)
if (over_ride_stop)
should_stop = false;
}
+ else if (current_plan->TracerExplainsStop())
+ {
+ return false;
+ }
else
{
// If the current plan doesn't explain the stop, then, find one that
@@ -346,8 +353,11 @@ Thread::PushPlan (ThreadPlanSP &thread_plan_sp)
{
if (thread_plan_sp)
{
+ // If the thread plan doesn't already have a tracer, give it its parent's tracer:
+ if (!thread_plan_sp->GetThreadPlanTracer())
+ thread_plan_sp->SetThreadPlanTracer(m_plan_stack.back()->GetThreadPlanTracer());
m_plan_stack.push_back (thread_plan_sp);
-
+
thread_plan_sp->DidPush();
LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
@@ -489,6 +499,29 @@ Thread::QueueThreadPlan (ThreadPlanSP &thread_plan_sp, bool abort_other_plans)
PushPlan (thread_plan_sp);
}
+
+void
+Thread::EnableTracer (bool value, bool single_stepping)
+{
+ int stack_size = m_plan_stack.size();
+ for (int i = 0; i < stack_size; i++)
+ {
+ if (m_plan_stack[i]->GetThreadPlanTracer())
+ {
+ m_plan_stack[i]->GetThreadPlanTracer()->EnableTracing(value);
+ m_plan_stack[i]->GetThreadPlanTracer()->EnableSingleStep(single_stepping);
+ }
+ }
+}
+
+void
+Thread::SetTracer (lldb::ThreadPlanTracerSP &tracer_sp)
+{
+ int stack_size = m_plan_stack.size();
+ for (int i = 0; i < stack_size; i++)
+ m_plan_stack[i]->SetThreadPlanTracer(tracer_sp);
+}
+
void
Thread::DiscardThreadPlansUpToPlan (lldb::ThreadPlanSP &up_to_plan_sp)
{
@@ -936,6 +969,49 @@ Thread::UpdateInstanceName ()
Thread::GetSettingsController()->RenameInstanceSettings (GetInstanceName().AsCString(), sstr.GetData());
}
+lldb::StackFrameSP
+Thread::GetStackFrameSPForStackFramePtr (StackFrame *stack_frame_ptr)
+{
+ return GetStackFrameList().GetStackFrameSPForStackFramePtr (stack_frame_ptr);
+}
+
+const char *
+Thread::StopReasonAsCString (lldb::StopReason reason)
+{
+ switch (reason)
+ {
+ case eStopReasonInvalid: return "invalid";
+ case eStopReasonNone: return "none";
+ case eStopReasonTrace: return "trace";
+ case eStopReasonBreakpoint: return "breakpoint";
+ case eStopReasonWatchpoint: return "watchpoint";
+ case eStopReasonSignal: return "signal";
+ case eStopReasonException: return "exception";
+ case eStopReasonPlanComplete: return "plan complete";
+ }
+
+
+ static char unknown_state_string[64];
+ snprintf(unknown_state_string, sizeof (unknown_state_string), "StopReason = %i", reason);
+ return unknown_state_string;
+}
+
+const char *
+Thread::RunModeAsCString (lldb::RunMode mode)
+{
+ switch (mode)
+ {
+ case eOnlyThisThread: return "only this thread";
+ case eAllThreads: return "all threads";
+ case eOnlyDuringStepping: return "only during stepping";
+ }
+
+ static char unknown_state_string[64];
+ snprintf(unknown_state_string, sizeof (unknown_state_string), "RunMode = %i", mode);
+ return unknown_state_string;
+}
+
+#pragma mark "Thread::ThreadSettingsController"
//--------------------------------------------------------------
// class Thread::ThreadSettingsController
//--------------------------------------------------------------
@@ -960,13 +1036,15 @@ Thread::ThreadSettingsController::CreateInstanceSettings (const char *instance_n
return new_settings_sp;
}
+#pragma mark "ThreadInstanceSettings"
//--------------------------------------------------------------
// class ThreadInstanceSettings
//--------------------------------------------------------------
ThreadInstanceSettings::ThreadInstanceSettings (UserSettingsController &owner, bool live_instance, const char *name) :
InstanceSettings (owner, (name == NULL ? InstanceSettings::InvalidName().AsCString() : name), live_instance),
- m_avoid_regexp_ap ()
+ m_avoid_regexp_ap (),
+ m_trace_enabled (false)
{
// CopyInstanceSettings is a pure virtual function in InstanceSettings; it therefore cannot be called
// until the vtables for ThreadInstanceSettings are properly set up, i.e. AFTER all the initializers.
@@ -989,7 +1067,8 @@ ThreadInstanceSettings::ThreadInstanceSettings (UserSettingsController &owner, b
ThreadInstanceSettings::ThreadInstanceSettings (const ThreadInstanceSettings &rhs) :
InstanceSettings (*(Thread::GetSettingsController().get()), CreateInstanceName().AsCString()),
- m_avoid_regexp_ap ()
+ m_avoid_regexp_ap (),
+ m_trace_enabled (rhs.m_trace_enabled)
{
if (m_instance_name != InstanceSettings::GetDefaultName())
{
@@ -1015,7 +1094,7 @@ ThreadInstanceSettings::operator= (const ThreadInstanceSettings &rhs)
else
m_avoid_regexp_ap.reset(NULL);
}
-
+ m_trace_enabled = rhs.m_trace_enabled;
return *this;
}
@@ -1044,6 +1123,26 @@ ThreadInstanceSettings::UpdateInstanceSettingsVariable (const ConstString &var_n
}
}
+ else if (var_name == GetTraceThreadVarName())
+ {
+ bool success;
+ bool result = Args::StringToBoolean(value, false, &success);
+
+ if (success)
+ {
+ m_trace_enabled = result;
+ if (!pending)
+ {
+ Thread *myself = static_cast<Thread *> (this);
+ myself->EnableTracer(m_trace_enabled, true);
+ }
+ }
+ else
+ {
+ err.SetErrorStringWithFormat ("Bad value \"%s\" for trace-thread, should be Boolean.", value);
+ }
+
+ }
}
void
@@ -1077,6 +1176,10 @@ ThreadInstanceSettings::GetInstanceSettingsValue (const SettingEntry &entry,
}
}
+ else if (var_name == GetTraceThreadVarName())
+ {
+ value.AppendString(m_trace_enabled ? "true" : "false");
+ }
else
{
if (err)
@@ -1102,9 +1205,17 @@ ThreadInstanceSettings::CreateInstanceName ()
const ConstString &
ThreadInstanceSettings::StepAvoidRegexpVarName ()
{
- static ConstString run_args_var_name ("step-avoid-regexp");
+ static ConstString step_avoid_var_name ("step-avoid-regexp");
- return run_args_var_name;
+ return step_avoid_var_name;
+}
+
+const ConstString &
+ThreadInstanceSettings::GetTraceThreadVarName ()
+{
+ static ConstString trace_thread_var_name ("trace-thread");
+
+ return trace_thread_var_name;
}
//--------------------------------------------------
@@ -1124,47 +1235,6 @@ Thread::ThreadSettingsController::instance_settings_table[] =
{
//{ "var-name", var-type, "default", enum-table, init'd, hidden, "help-text"},
{ "step-avoid-regexp", eSetVarTypeString, "", NULL, false, false, "A regular expression defining functions step-in won't stop in." },
+ { "trace-thread", eSetVarTypeBoolean, "false", NULL, false, false, "If true, this thread will single-step and log execution." },
{ NULL, eSetVarTypeNone, NULL, NULL, 0, 0, NULL }
};
-
-lldb::StackFrameSP
-Thread::GetStackFrameSPForStackFramePtr (StackFrame *stack_frame_ptr)
-{
- return GetStackFrameList().GetStackFrameSPForStackFramePtr (stack_frame_ptr);
-}
-
-const char *
-Thread::StopReasonAsCString (lldb::StopReason reason)
-{
- switch (reason)
- {
- case eStopReasonInvalid: return "invalid";
- case eStopReasonNone: return "none";
- case eStopReasonTrace: return "trace";
- case eStopReasonBreakpoint: return "breakpoint";
- case eStopReasonWatchpoint: return "watchpoint";
- case eStopReasonSignal: return "signal";
- case eStopReasonException: return "exception";
- case eStopReasonPlanComplete: return "plan complete";
- }
-
-
- static char unknown_state_string[64];
- snprintf(unknown_state_string, sizeof (unknown_state_string), "StopReason = %i", reason);
- return unknown_state_string;
-}
-
-const char *
-Thread::RunModeAsCString (lldb::RunMode mode)
-{
- switch (mode)
- {
- case eOnlyThisThread: return "only this thread";
- case eAllThreads: return "all threads";
- case eOnlyDuringStepping: return "only during stepping";
- }
-
- static char unknown_state_string[64];
- snprintf(unknown_state_string, sizeof (unknown_state_string), "RunMode = %i", mode);
- return unknown_state_string;
-}
OpenPOWER on IntegriCloud