[Lldb-commits] [lldb] r156105 - in /lldb/branches/lldb-platform-work: ./ include/lldb/API/ include/lldb/Target/ lldb.xcodeproj/ source/API/ source/Commands/ source/Target/ tools/debugserver/debugserver.xcodeproj/
Johnny Chen
johnny.chen at apple.com
Thu May 3 14:36:32 PDT 2012
Author: johnny
Date: Thu May 3 16:36:31 2012
New Revision: 156105
URL: http://llvm.org/viewvc/llvm-project?rev=156105&view=rev
Log:
Merge changes from ToT trunk:
svn merge -r 156088:156101 https://johnny@llvm.org/svn/llvm-project/lldb/trunk .
Modified:
lldb/branches/lldb-platform-work/ (props changed)
lldb/branches/lldb-platform-work/include/lldb/API/SBThread.h
lldb/branches/lldb-platform-work/include/lldb/Target/Thread.h
lldb/branches/lldb-platform-work/include/lldb/Target/ThreadPlan.h
lldb/branches/lldb-platform-work/include/lldb/Target/ThreadPlanStepOut.h
lldb/branches/lldb-platform-work/include/lldb/Target/ThreadPlanStepOverRange.h
lldb/branches/lldb-platform-work/include/lldb/Target/ThreadPlanStepRange.h
lldb/branches/lldb-platform-work/lldb.xcodeproj/project.pbxproj
lldb/branches/lldb-platform-work/source/API/SBThread.cpp
lldb/branches/lldb-platform-work/source/Commands/CommandObjectBreakpoint.cpp
lldb/branches/lldb-platform-work/source/Commands/CommandObjectThread.cpp
lldb/branches/lldb-platform-work/source/Target/Thread.cpp
lldb/branches/lldb-platform-work/source/Target/ThreadPlan.cpp
lldb/branches/lldb-platform-work/source/Target/ThreadPlanStepInstruction.cpp
lldb/branches/lldb-platform-work/source/Target/ThreadPlanStepOut.cpp
lldb/branches/lldb-platform-work/source/Target/ThreadPlanStepOverRange.cpp
lldb/branches/lldb-platform-work/source/Target/ThreadPlanStepRange.cpp
lldb/branches/lldb-platform-work/source/Target/ThreadPlanStepUntil.cpp
lldb/branches/lldb-platform-work/tools/debugserver/debugserver.xcodeproj/project.pbxproj
Propchange: lldb/branches/lldb-platform-work/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Thu May 3 16:36:31 2012
@@ -1 +1 @@
-/lldb/trunk:154223-156088
+/lldb/trunk:154223-156101
Modified: lldb/branches/lldb-platform-work/include/lldb/API/SBThread.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/include/lldb/API/SBThread.h?rev=156105&r1=156104&r2=156105&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/include/lldb/API/SBThread.h (original)
+++ lldb/branches/lldb-platform-work/include/lldb/API/SBThread.h Thu May 3 16:36:31 2012
@@ -172,6 +172,11 @@
void
SetThread (const lldb::ThreadSP& lldb_object_sp);
+#ifndef SWIG
+ SBError
+ ResumeNewPlan (lldb_private::ExecutionContext &exe_ctx, lldb_private::ThreadPlan *new_plan);
+#endif
+
private:
lldb::ExecutionContextRefSP m_opaque_sp;
};
Modified: lldb/branches/lldb-platform-work/include/lldb/Target/Thread.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/include/lldb/Target/Thread.h?rev=156105&r1=156104&r2=156105&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/include/lldb/Target/Thread.h (original)
+++ lldb/branches/lldb-platform-work/include/lldb/Target/Thread.h Thu May 3 16:36:31 2012
@@ -674,6 +674,9 @@
void
DiscardThreadPlansUpToPlan (lldb::ThreadPlanSP &up_to_plan_sp);
+ void
+ DiscardThreadPlansUpToPlan (ThreadPlan *up_to_plan_ptr);
+
//------------------------------------------------------------------
/// Prints the current plan stack.
///
Modified: lldb/branches/lldb-platform-work/include/lldb/Target/ThreadPlan.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/include/lldb/Target/ThreadPlan.h?rev=156105&r1=156104&r2=156105&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/include/lldb/Target/ThreadPlan.h (original)
+++ lldb/branches/lldb-platform-work/include/lldb/Target/ThreadPlan.h Thu May 3 16:36:31 2012
@@ -115,12 +115,33 @@
// figure out what to do about the plans below it in the stack. If the stop is recoverable, then the plan that
// understands it can just do what it needs to set up to restart, and then continue.
// Otherwise, the plan that understood the stop should call DiscardPlanStack to clean up the stack below it.
-// In the normal case, this will just collapse the plan stack up to the point of the plan that understood
+//
+// Master plans:
+//
+// In the normal case, when we decide to stop, we will collapse the plan stack up to the point of the plan that understood
// the stop reason. However, if a plan wishes to stay on the stack after an event it didn't directly handle
// it can designate itself a "Master" plan by responding true to IsMasterPlan, and then if it wants not to be
// discarded, it can return true to OkayToDiscard, and it and all its dependent plans will be preserved when
// we resume execution.
//
+// The other effect of being a master plan is that when the Master plan is done , if it has set "OkayToDiscard" to false,
+// then it will be popped & execution will stop and return to the user. Remember that if OkayToDiscard is false, the
+// plan will be popped and control will be given to the next plan above it on the stack So setting OkayToDiscard to
+// false means the user will regain control when the MasterPlan is completed.
+//
+// Between these two controls this allows things like: a MasterPlan/DontDiscard Step Over to hit a breakpoint, stop and
+// return control to the user, but then when the user continues, the step out succeeds.
+// Even more tricky, when the breakpoint is hit, the user can continue to step in/step over/etc, and finally when they
+// continue, they will finish up the Step Over.
+//
+// FIXME: MasterPlan & OkayToDiscard aren't really orthogonal. MasterPlan designation means that this plan controls
+// it's fate and the fate of plans below it. OkayToDiscard tells whether the MasterPlan wants to stay on the stack. I
+// originally thought "MasterPlan-ness" would need to be a fixed characteristic of a ThreadPlan, in which case you needed
+// the extra control. But that doesn't seem to be true. So we should be able to convert to only MasterPlan status to mean
+// the current "MasterPlan/DontDiscard". Then no plans would be MasterPlans by default, and you would set the ones you
+// wanted to be "user level" in this way.
+//
+//
// Actually Stopping:
//
// If a plan says responds "true" to ShouldStop, then it is asked if it's job is complete by calling
@@ -152,6 +173,18 @@
// because of a crash or breakpoint hit, it wants to unship itself, because it isn't so useful to have step in keep going
// after a breakpoint hit. But it can't be the reason for the stop or no-one would see that they had hit a breakpoint.
//
+// Cleaning up the plan stack:
+//
+// One of the complications of MasterPlans is that you may get past the limits of a plan without triggering it to clean
+// itself up. For instance, if you are doing a MasterPlan StepOver, and hit a breakpoint in a called function, then
+// step over enough times to step out of the initial StepOver range, each of the step overs will explain the stop &
+// take themselves off the stack, but control would never be returned to the original StepOver. Eventually, the user
+// will continue, and when that continue stops, the old stale StepOver plan that was left on the stack will get woken
+// up and notice it is done. But that can leave junk on the stack for a while. To avoid that, the plans implement a
+// "IsPlanStale" method, that can check whether it is relevant anymore. On stop, after the regular plan negotiation,
+// the remaining plan stack is consulted and if any plan says it is stale, it and the plans below it are discarded from
+// the stack.
+//
// Automatically Resuming:
//
// If ShouldStop for all threads returns "false", then the target process will resume. This then cycles back to
@@ -408,6 +441,12 @@
void
SetPlanComplete (bool success = true);
+ virtual bool
+ IsPlanStale ()
+ {
+ return false;
+ }
+
bool
PlanSucceeded ()
{
Modified: lldb/branches/lldb-platform-work/include/lldb/Target/ThreadPlanStepOut.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/include/lldb/Target/ThreadPlanStepOut.h?rev=156105&r1=156104&r2=156105&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/include/lldb/Target/ThreadPlanStepOut.h (original)
+++ lldb/branches/lldb-platform-work/include/lldb/Target/ThreadPlanStepOut.h Thu May 3 16:36:31 2012
@@ -42,6 +42,7 @@
virtual bool WillStop ();
virtual bool MischiefManaged ();
virtual void DidPush();
+ virtual bool IsPlanStale();
virtual lldb::ValueObjectSP GetReturnValueObject()
{
Modified: lldb/branches/lldb-platform-work/include/lldb/Target/ThreadPlanStepOverRange.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/include/lldb/Target/ThreadPlanStepOverRange.h?rev=156105&r1=156104&r2=156105&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/include/lldb/Target/ThreadPlanStepOverRange.h (original)
+++ lldb/branches/lldb-platform-work/include/lldb/Target/ThreadPlanStepOverRange.h Thu May 3 16:36:31 2012
@@ -28,8 +28,7 @@
ThreadPlanStepOverRange (Thread &thread,
const AddressRange &range,
const SymbolContext &addr_context,
- lldb::RunMode stop_others,
- bool okay_to_discard = false);
+ lldb::RunMode stop_others);
virtual ~ThreadPlanStepOverRange ();
Modified: lldb/branches/lldb-platform-work/include/lldb/Target/ThreadPlanStepRange.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/include/lldb/Target/ThreadPlanStepRange.h?rev=156105&r1=156104&r2=156105&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/include/lldb/Target/ThreadPlanStepRange.h (original)
+++ lldb/branches/lldb-platform-work/include/lldb/Target/ThreadPlanStepRange.h Thu May 3 16:36:31 2012
@@ -43,6 +43,7 @@
virtual bool WillStop ();
virtual bool MischiefManaged ();
virtual void DidPush ();
+ virtual bool IsPlanStale ();
void AddRange(const AddressRange &new_range);
Modified: lldb/branches/lldb-platform-work/lldb.xcodeproj/project.pbxproj
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/lldb.xcodeproj/project.pbxproj?rev=156105&r1=156104&r2=156105&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/lldb.xcodeproj/project.pbxproj (original)
+++ lldb/branches/lldb-platform-work/lldb.xcodeproj/project.pbxproj Thu May 3 16:36:31 2012
@@ -4119,10 +4119,7 @@
ALWAYS_SEARCH_USER_PATHS = NO;
ARCHS = "$(NATIVE_ARCH)";
"ARCHS[sdk=iphoneos*]" = armv7;
- "ARCHS[sdk=macosx*]" = (
- x86_64,
- i386,
- );
+ "ARCHS[sdk=macosx*]" = "$(ARCHS_STANDARD_64_BIT)";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
GCC_C_LANGUAGE_STANDARD = gnu99;
Modified: lldb/branches/lldb-platform-work/source/API/SBThread.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/API/SBThread.cpp?rev=156105&r1=156104&r2=156105&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/API/SBThread.cpp (original)
+++ lldb/branches/lldb-platform-work/source/API/SBThread.cpp Thu May 3 16:36:31 2012
@@ -474,6 +474,47 @@
return name;
}
+SBError
+SBThread::ResumeNewPlan (ExecutionContext &exe_ctx, ThreadPlan *new_plan)
+{
+ SBError sb_error;
+
+ Process *process = exe_ctx.GetProcessPtr();
+ if (!process)
+ {
+ sb_error.SetErrorString("No process in SBThread::ResumeNewPlan");
+ return sb_error;
+ }
+
+ Thread *thread = exe_ctx.GetThreadPtr();
+ if (!thread)
+ {
+ sb_error.SetErrorString("No thread in SBThread::ResumeNewPlan");
+ return sb_error;
+ }
+
+ // User level plans should be Master Plans so they can be interrupted, other plans executed, and
+ // then a "continue" will resume the plan.
+ if (new_plan != NULL)
+ {
+ new_plan->SetIsMasterPlan(true);
+ new_plan->SetOkayToDiscard(false);
+ }
+
+ // Why do we need to set the current thread by ID here???
+ process->GetThreadList().SetSelectedThreadByID (thread->GetID());
+ sb_error.ref() = process->Resume();
+
+ if (sb_error.Success())
+ {
+ // If we are doing synchronous mode, then wait for the
+ // process to stop yet again!
+ if (process->GetTarget().GetDebugger().GetAsyncExecution () == false)
+ process->WaitForProcessToStop (NULL);
+ }
+
+ return sb_error;
+}
void
SBThread::StepOver (lldb::RunMode stop_other_threads)
@@ -492,39 +533,31 @@
Thread *thread = exe_ctx.GetThreadPtr();
bool abort_other_plans = true;
StackFrameSP frame_sp(thread->GetStackFrameAtIndex (0));
+ ThreadPlan *new_plan = NULL;
if (frame_sp)
{
if (frame_sp->HasDebugInformation ())
{
SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything));
- thread->QueueThreadPlanForStepRange (abort_other_plans,
- eStepTypeOver,
- sc.line_entry.range,
- sc,
- stop_other_threads,
- false);
+ new_plan = thread->QueueThreadPlanForStepRange (abort_other_plans,
+ eStepTypeOver,
+ sc.line_entry.range,
+ sc,
+ stop_other_threads,
+ false);
}
else
{
- thread->QueueThreadPlanForStepSingleInstruction (true,
- abort_other_plans,
- stop_other_threads);
+ new_plan = thread->QueueThreadPlanForStepSingleInstruction (true,
+ abort_other_plans,
+ stop_other_threads);
}
}
- Process *process = exe_ctx.GetProcessPtr();
- // Why do we need to set the current thread by ID here???
- process->GetThreadList().SetSelectedThreadByID (thread->GetID());
- Error error (process->Resume());
- if (error.Success())
- {
- // If we are doing synchronous mode, then wait for the
- // process to stop yet again!
- if (process->GetTarget().GetDebugger().GetAsyncExecution () == false)
- process->WaitForProcessToStop (NULL);
- }
+ // This returns an error, we should use it!
+ ResumeNewPlan (exe_ctx, new_plan);
}
}
@@ -545,36 +578,28 @@
Thread *thread = exe_ctx.GetThreadPtr();
StackFrameSP frame_sp(thread->GetStackFrameAtIndex (0));
+ ThreadPlan *new_plan = NULL;
if (frame_sp && frame_sp->HasDebugInformation ())
{
bool avoid_code_without_debug_info = true;
SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything));
- thread->QueueThreadPlanForStepRange (abort_other_plans,
- eStepTypeInto,
- sc.line_entry.range,
- sc,
- stop_other_threads,
- avoid_code_without_debug_info);
+ new_plan = thread->QueueThreadPlanForStepRange (abort_other_plans,
+ eStepTypeInto,
+ sc.line_entry.range,
+ sc,
+ stop_other_threads,
+ avoid_code_without_debug_info);
}
else
{
- thread->QueueThreadPlanForStepSingleInstruction (false,
- abort_other_plans,
- stop_other_threads);
- }
-
- Process *process = exe_ctx.GetProcessPtr();
- // Why do we need to set the current thread by ID here???
- process->GetThreadList().SetSelectedThreadByID (thread->GetID());
- Error error (process->Resume());
- if (error.Success())
- {
- // If we are doing synchronous mode, then wait for the
- // process to stop yet again!
- if (process->GetTarget().GetDebugger().GetAsyncExecution () == false)
- process->WaitForProcessToStop (NULL);
+ new_plan = thread->QueueThreadPlanForStepSingleInstruction (false,
+ abort_other_plans,
+ stop_other_threads);
}
+
+ // This returns an error, we should use it!
+ ResumeNewPlan (exe_ctx, new_plan);
}
}
@@ -596,24 +621,16 @@
Thread *thread = exe_ctx.GetThreadPtr();
- thread->QueueThreadPlanForStepOut (abort_other_plans,
- NULL,
- false,
- stop_other_threads,
- eVoteYes,
- eVoteNoOpinion,
- 0);
-
- Process *process = exe_ctx.GetProcessPtr();
- process->GetThreadList().SetSelectedThreadByID (thread->GetID());
- Error error (process->Resume());
- if (error.Success())
- {
- // If we are doing synchronous mode, then wait for the
- // process to stop yet again!
- if (process->GetTarget().GetDebugger().GetAsyncExecution () == false)
- process->WaitForProcessToStop (NULL);
- }
+ ThreadPlan *new_plan = thread->QueueThreadPlanForStepOut (abort_other_plans,
+ NULL,
+ false,
+ stop_other_threads,
+ eVoteYes,
+ eVoteNoOpinion,
+ 0);
+
+ // This returns an error, we should use it!
+ ResumeNewPlan (exe_ctx, new_plan);
}
}
@@ -638,24 +655,16 @@
bool stop_other_threads = true;
Thread *thread = exe_ctx.GetThreadPtr();
- thread->QueueThreadPlanForStepOut (abort_other_plans,
- NULL,
- false,
- stop_other_threads,
- eVoteYes,
- eVoteNoOpinion,
- frame_sp->GetFrameIndex());
-
- Process *process = exe_ctx.GetProcessPtr();
- process->GetThreadList().SetSelectedThreadByID (thread->GetID());
- Error error (process->Resume());
- if (error.Success())
- {
- // If we are doing synchronous mode, then wait for the
- // process to stop yet again!
- if (process->GetTarget().GetDebugger().GetAsyncExecution () == false)
- process->WaitForProcessToStop (NULL);
- }
+ ThreadPlan *new_plan = thread->QueueThreadPlanForStepOut (abort_other_plans,
+ NULL,
+ false,
+ stop_other_threads,
+ eVoteYes,
+ eVoteNoOpinion,
+ frame_sp->GetFrameIndex());
+
+ // This returns an error, we should use it!
+ ResumeNewPlan (exe_ctx, new_plan);
}
}
@@ -674,17 +683,10 @@
{
Mutex::Locker api_locker (exe_ctx.GetTargetPtr()->GetAPIMutex());
Thread *thread = exe_ctx.GetThreadPtr();
- Process *process = exe_ctx.GetProcessPtr();
- thread->QueueThreadPlanForStepSingleInstruction (step_over, true, true);
- process->GetThreadList().SetSelectedThreadByID (thread->GetID());
- Error error (process->Resume());
- if (error.Success())
- {
- // If we are doing synchronous mode, then wait for the
- // process to stop yet again!
- if (process->GetTarget().GetDebugger().GetAsyncExecution () == false)
- process->WaitForProcessToStop (NULL);
- }
+ ThreadPlan *new_plan = thread->QueueThreadPlanForStepSingleInstruction (step_over, true, true);
+
+ // This returns an error, we should use it!
+ ResumeNewPlan (exe_ctx, new_plan);
}
}
@@ -707,18 +709,11 @@
Address target_addr (addr);
Thread *thread = exe_ctx.GetThreadPtr();
- Process *process = exe_ctx.GetProcessPtr();
- thread->QueueThreadPlanForRunToAddress (abort_other_plans, target_addr, stop_other_threads);
- process->GetThreadList().SetSelectedThreadByID (thread->GetID());
- Error error (process->Resume());
- if (error.Success())
- {
- // If we are doing synchronous mode, then wait for the
- // process to stop yet again!
- if (process->GetTarget().GetDebugger().GetAsyncExecution () == false)
- process->WaitForProcessToStop (NULL);
- }
+ ThreadPlan *new_plan = thread->QueueThreadPlanForRunToAddress (abort_other_plans, target_addr, stop_other_threads);
+
+ // This returns an error, we should use it!
+ ResumeNewPlan (exe_ctx, new_plan);
}
}
@@ -854,23 +849,13 @@
}
else
{
- thread->QueueThreadPlanForStepUntil (abort_other_plans,
- &step_over_until_addrs[0],
- step_over_until_addrs.size(),
- stop_other_threads,
- frame_sp->GetFrameIndex());
-
- Process *process = exe_ctx.GetProcessPtr();
-
- process->GetThreadList().SetSelectedThreadByID (thread->GetID());
- sb_error.ref() = process->Resume();
- if (sb_error->Success())
- {
- // If we are doing synchronous mode, then wait for the
- // process to stop yet again!
- if (process->GetTarget().GetDebugger().GetAsyncExecution () == false)
- process->WaitForProcessToStop (NULL);
- }
+ ThreadPlan *new_plan = thread->QueueThreadPlanForStepUntil (abort_other_plans,
+ &step_over_until_addrs[0],
+ step_over_until_addrs.size(),
+ stop_other_threads,
+ frame_sp->GetFrameIndex());
+
+ sb_error = ResumeNewPlan (exe_ctx, new_plan);
}
}
else
Modified: lldb/branches/lldb-platform-work/source/Commands/CommandObjectBreakpoint.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Commands/CommandObjectBreakpoint.cpp?rev=156105&r1=156104&r2=156105&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Commands/CommandObjectBreakpoint.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Commands/CommandObjectBreakpoint.cpp Thu May 3 16:36:31 2012
@@ -81,7 +81,8 @@
CommandObjectBreakpointSet::CommandOptions::g_option_table[] =
{
{ LLDB_OPT_NOT_10, false, "shlib", 's', required_argument, NULL, CommandCompletions::eModuleCompletion, eArgTypeShlibName,
- "Set the breakpoint only in this shared library (can use this option multiple times for multiple shlibs)."},
+ "Set the breakpoint only in this shared library. "
+ "Can repeat this option multiple times to specify multiple shared libraries."},
{ LLDB_OPT_SET_ALL, false, "ignore-count", 'i', required_argument, NULL, 0, eArgTypeCount,
"Set the number of times this breakpoint is skipped before stopping." },
@@ -113,23 +114,25 @@
"Set the breakpoint by address, at the specified address."},
{ LLDB_OPT_SET_3, true, "name", 'n', required_argument, NULL, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName,
- "Set the breakpoint by function name." },
+ "Set the breakpoint by function name. Can be repeated multiple times to make one breakpoint for multiple snames" },
{ LLDB_OPT_SET_4, true, "fullname", 'F', required_argument, NULL, CommandCompletions::eSymbolCompletion, eArgTypeFullName,
- "Set the breakpoint by fully qualified function names. For C++ this means namespaces and all arguemnts, and "
- "for Objective C this means a full function prototype with class and selector." },
+ "Set the breakpoint by fully qualified function names. For C++ this means namespaces and all arguments, and "
+ "for Objective C this means a full function prototype with class and selector. "
+ "Can be repeated multiple times to make one breakpoint for multiple names." },
{ LLDB_OPT_SET_5, true, "selector", 'S', required_argument, NULL, 0, eArgTypeSelector,
- "Set the breakpoint by ObjC selector name." },
+ "Set the breakpoint by ObjC selector name. Can be repeated multiple times to make one breakpoint for multiple Selectors." },
{ LLDB_OPT_SET_6, true, "method", 'M', required_argument, NULL, 0, eArgTypeMethod,
- "Set the breakpoint by C++ method names." },
+ "Set the breakpoint by C++ method names. Can be repeated multiple times to make one breakpoint for multiple methods." },
{ LLDB_OPT_SET_7, true, "func-regex", 'r', required_argument, NULL, 0, eArgTypeRegularExpression,
"Set the breakpoint by function name, evaluating a regular-expression to find the function name(s)." },
{ LLDB_OPT_SET_8, true, "basename", 'b', required_argument, NULL, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName,
- "Set the breakpoint by function basename (C++ namespaces and arguments will be ignored)." },
+ "Set the breakpoint by function basename (C++ namespaces and arguments will be ignored). "
+ "Can be repeated multiple times to make one breakpoint for multiple symbols." },
{ LLDB_OPT_SET_9, true, "source-pattern-regexp", 'p', required_argument, NULL, 0, eArgTypeRegularExpression,
"Set the breakpoint specifying a regular expression to match a pattern in the source text in a given source file." },
Modified: lldb/branches/lldb-platform-work/source/Commands/CommandObjectThread.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Commands/CommandObjectThread.cpp?rev=156105&r1=156104&r2=156105&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Commands/CommandObjectThread.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Commands/CommandObjectThread.cpp Thu May 3 16:36:31 2012
@@ -451,10 +451,11 @@
else
bool_stop_other_threads = true;
+ ThreadPlan *new_plan = NULL;
+
if (m_step_type == eStepTypeInto)
{
StackFrame *frame = thread->GetStackFrameAtIndex(0).get();
- ThreadPlan *new_plan;
if (frame->HasDebugInformation ())
{
@@ -471,14 +472,11 @@
}
else
new_plan = thread->QueueThreadPlanForStepSingleInstruction (false, abort_other_plans, bool_stop_other_threads);
-
- process->GetThreadList().SetSelectedThreadByID (thread->GetID());
- process->Resume ();
+
}
else if (m_step_type == eStepTypeOver)
{
StackFrame *frame = thread->GetStackFrameAtIndex(0).get();
- ThreadPlan *new_plan;
if (frame->HasDebugInformation())
new_plan = thread->QueueThreadPlanForStepRange (abort_other_plans,
@@ -492,29 +490,17 @@
abort_other_plans,
bool_stop_other_threads);
- // FIXME: This will keep the step plan on the thread stack when we hit a breakpoint while stepping over.
- // Maybe there should be a parameter to control this.
- new_plan->SetOkayToDiscard(false);
-
- process->GetThreadList().SetSelectedThreadByID (thread->GetID());
- process->Resume ();
}
else if (m_step_type == eStepTypeTrace)
{
- thread->QueueThreadPlanForStepSingleInstruction (false, abort_other_plans, bool_stop_other_threads);
- process->GetThreadList().SetSelectedThreadByID (thread->GetID());
- process->Resume ();
+ new_plan = thread->QueueThreadPlanForStepSingleInstruction (false, abort_other_plans, bool_stop_other_threads);
}
else if (m_step_type == eStepTypeTraceOver)
{
- thread->QueueThreadPlanForStepSingleInstruction (true, abort_other_plans, bool_stop_other_threads);
- process->GetThreadList().SetSelectedThreadByID (thread->GetID());
- process->Resume ();
+ new_plan = thread->QueueThreadPlanForStepSingleInstruction (true, abort_other_plans, bool_stop_other_threads);
}
else if (m_step_type == eStepTypeOut)
{
- ThreadPlan *new_plan;
-
new_plan = thread->QueueThreadPlanForStepOut (abort_other_plans,
NULL,
false,
@@ -522,32 +508,46 @@
eVoteYes,
eVoteNoOpinion,
thread->GetSelectedFrameIndex());
- // FIXME: This will keep the step plan on the thread stack when we hit a breakpoint while stepping over.
- // Maybe there should be a parameter to control this.
- new_plan->SetOkayToDiscard(false);
-
- process->GetThreadList().SetSelectedThreadByID (thread->GetID());
- process->Resume ();
}
else
{
result.AppendError ("step type is not supported");
result.SetStatus (eReturnStatusFailed);
+ return false;
}
- if (synchronous_execution)
+
+ // If we got a new plan, then set it to be a master plan (User level Plans should be master plans
+ // so that they can be interruptible). Then resume the process.
+
+ if (new_plan != NULL)
{
- StateType state = process->WaitForProcessToStop (NULL);
-
- //EventSP event_sp;
- //StateType state = process->WaitForStateChangedEvents (NULL, event_sp);
- //while (! StateIsStoppedState (state))
- // {
- // state = process->WaitForStateChangedEvents (NULL, event_sp);
- // }
+ new_plan->SetIsMasterPlan (true);
+ new_plan->SetOkayToDiscard (false);
+
process->GetThreadList().SetSelectedThreadByID (thread->GetID());
- result.SetDidChangeProcessState (true);
- result.AppendMessageWithFormat ("Process %llu %s\n", process->GetID(), StateAsCString (state));
- result.SetStatus (eReturnStatusSuccessFinishNoResult);
+ process->Resume ();
+
+
+ if (synchronous_execution)
+ {
+ StateType state = process->WaitForProcessToStop (NULL);
+
+ //EventSP event_sp;
+ //StateType state = process->WaitForStateChangedEvents (NULL, event_sp);
+ //while (! StateIsStoppedState (state))
+ // {
+ // state = process->WaitForStateChangedEvents (NULL, event_sp);
+ // }
+ process->GetThreadList().SetSelectedThreadByID (thread->GetID());
+ result.SetDidChangeProcessState (true);
+ result.AppendMessageWithFormat ("Process %llu %s\n", process->GetID(), StateAsCString (state));
+ result.SetStatus (eReturnStatusSuccessFinishNoResult);
+ }
+ }
+ else
+ {
+ result.AppendError ("Couldn't find thread plan to implement step type.");
+ result.SetStatus (eReturnStatusFailed);
}
}
return result.Succeeded();
@@ -959,7 +959,7 @@
return false;
}
- ThreadPlan *new_plan;
+ ThreadPlan *new_plan = NULL;
if (frame->HasDebugInformation ())
{
@@ -1027,6 +1027,10 @@
address_list.size(),
m_options.m_stop_others,
thread->GetSelectedFrameIndex ());
+ // User level plans should be master plans so they can be interrupted (e.g. by hitting a breakpoint)
+ // and other plans executed by the user (stepping around the breakpoint) and then a "continue"
+ // will resume the original plan.
+ new_plan->SetIsMasterPlan (true);
new_plan->SetOkayToDiscard(false);
}
else
Modified: lldb/branches/lldb-platform-work/source/Target/Thread.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Target/Thread.cpp?rev=156105&r1=156104&r2=156105&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Target/Thread.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Target/Thread.cpp Thu May 3 16:36:31 2012
@@ -455,8 +455,33 @@
}
}
}
+
if (over_ride_stop)
should_stop = false;
+
+ // One other potential problem is that we set up a master plan, then stop in before it is complete - for instance
+ // by hitting a breakpoint during a step-over - then do some step/finish/etc operations that wind up
+ // past the end point condition of the initial plan. We don't want to strand the original plan on the stack,
+ // This code clears stale plans off the stack.
+
+ if (should_stop)
+ {
+ ThreadPlan *plan_ptr = GetCurrentPlan();
+ while (!PlanIsBasePlan(plan_ptr))
+ {
+ bool stale = plan_ptr->IsPlanStale ();
+ ThreadPlan *examined_plan = plan_ptr;
+ plan_ptr = GetPreviousPlan (examined_plan);
+
+ if (stale)
+ {
+ if (log)
+ log->Printf("Plan %s being discarded in cleanup, it says it is already done.", examined_plan->GetName());
+ DiscardThreadPlansUpToPlan(examined_plan);
+ }
+ }
+ }
+
}
if (log)
@@ -750,10 +775,16 @@
void
Thread::DiscardThreadPlansUpToPlan (lldb::ThreadPlanSP &up_to_plan_sp)
{
+ DiscardThreadPlansUpToPlan (up_to_plan_sp.get());
+}
+
+void
+Thread::DiscardThreadPlansUpToPlan (ThreadPlan *up_to_plan_ptr)
+{
LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
if (log)
{
- log->Printf("Discarding thread plans for thread tid = 0x%4.4llx, up to %p", GetID(), up_to_plan_sp.get());
+ log->Printf("Discarding thread plans for thread tid = 0x%4.4llx, up to %p", GetID(), up_to_plan_ptr);
}
int stack_size = m_plan_stack.size();
@@ -761,7 +792,7 @@
// If the input plan is NULL, discard all plans. Otherwise make sure this plan is in the
// stack, and if so discard up to and including it.
- if (up_to_plan_sp.get() == NULL)
+ if (up_to_plan_ptr == NULL)
{
for (int i = stack_size - 1; i > 0; i--)
DiscardPlan();
@@ -771,7 +802,7 @@
bool found_it = false;
for (int i = stack_size - 1; i > 0; i--)
{
- if (m_plan_stack[i] == up_to_plan_sp)
+ if (m_plan_stack[i].get() == up_to_plan_ptr)
found_it = true;
}
if (found_it)
@@ -779,7 +810,7 @@
bool last_one = false;
for (int i = stack_size - 1; i > 0 && !last_one ; i--)
{
- if (GetCurrentPlan() == up_to_plan_sp.get())
+ if (GetCurrentPlan() == up_to_plan_ptr)
last_one = true;
DiscardPlan();
}
Modified: lldb/branches/lldb-platform-work/source/Target/ThreadPlan.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Target/ThreadPlan.cpp?rev=156105&r1=156104&r2=156105&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Target/ThreadPlan.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Target/ThreadPlan.cpp Thu May 3 16:36:31 2012
@@ -36,7 +36,7 @@
m_plan_complete_mutex (Mutex::eMutexTypeRecursive),
m_plan_complete (false),
m_plan_private (false),
- m_okay_to_discard (false),
+ m_okay_to_discard (true),
m_is_master_plan (false),
m_plan_succeeded(true)
{
Modified: lldb/branches/lldb-platform-work/source/Target/ThreadPlanStepInstruction.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Target/ThreadPlanStepInstruction.cpp?rev=156105&r1=156104&r2=156105&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Target/ThreadPlanStepInstruction.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Target/ThreadPlanStepInstruction.cpp Thu May 3 16:36:31 2012
@@ -131,7 +131,13 @@
s.Address (return_addr, m_thread.CalculateTarget()->GetArchitecture().GetAddressByteSize());
log->Printf("%s.", s.GetData());
}
- m_thread.QueueThreadPlanForStepOut(false, NULL, true, m_stop_other_threads, eVoteNo, eVoteNoOpinion, 0);
+ m_thread.QueueThreadPlanForStepOut(false,
+ NULL,
+ true,
+ m_stop_other_threads,
+ eVoteNo,
+ eVoteNoOpinion,
+ 0);
return false;
}
else
Modified: lldb/branches/lldb-platform-work/source/Target/ThreadPlanStepOut.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Target/ThreadPlanStepOut.cpp?rev=156105&r1=156104&r2=156105&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Target/ThreadPlanStepOut.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Target/ThreadPlanStepOut.cpp Thu May 3 16:36:31 2012
@@ -81,7 +81,6 @@
eVoteNoOpinion,
eVoteNoOpinion,
frame_idx - 1));
- m_step_out_plan_sp->SetOkayToDiscard(true);
}
else
{
@@ -468,3 +467,17 @@
}
}
}
+
+bool
+ThreadPlanStepOut::IsPlanStale()
+{
+ // If we are still lower on the stack than the frame we are returning to, then
+ // there's something for us to do. Otherwise, we're stale.
+
+ StackID frame_zero_id = m_thread.GetStackFrameAtIndex(0)->GetStackID();
+ if (frame_zero_id < m_step_out_to_id)
+ return false;
+ else
+ return true;
+}
+
Modified: lldb/branches/lldb-platform-work/source/Target/ThreadPlanStepOverRange.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Target/ThreadPlanStepOverRange.cpp?rev=156105&r1=156104&r2=156105&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Target/ThreadPlanStepOverRange.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Target/ThreadPlanStepOverRange.cpp Thu May 3 16:36:31 2012
@@ -38,15 +38,10 @@
Thread &thread,
const AddressRange &range,
const SymbolContext &addr_context,
- lldb::RunMode stop_others,
- bool okay_to_discard
+ lldb::RunMode stop_others
) :
ThreadPlanStepRange (ThreadPlan::eKindStepOverRange, "Step range stepping over", thread, range, addr_context, stop_others)
{
- // Step over range plans can be master plans, since you could hit a breakpoint while stepping over, step around
- // a bit, then continue to finish up the step over.
- SetIsMasterPlan (true);
- SetOkayToDiscard (okay_to_discard);
}
ThreadPlanStepOverRange::~ThreadPlanStepOverRange ()
Modified: lldb/branches/lldb-platform-work/source/Target/ThreadPlanStepRange.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Target/ThreadPlanStepRange.cpp?rev=156105&r1=156104&r2=156105&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Target/ThreadPlanStepRange.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Target/ThreadPlanStepRange.cpp Thu May 3 16:36:31 2012
@@ -403,3 +403,30 @@
}
}
+
+bool
+ThreadPlanStepRange::IsPlanStale ()
+{
+ LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
+ FrameComparison frame_order = CompareCurrentFrameToStartFrame();
+
+ if (frame_order == eFrameCompareOlder)
+ {
+ if (log)
+ {
+ log->Printf("ThreadPlanStepRange::IsPlanStale returning true, we've stepped out.");
+ }
+ return true;
+ }
+ else if (frame_order == eFrameCompareEqual && InSymbol())
+ {
+ // If we are not in a place we should step through, we've gotten stale.
+ // One tricky bit here is that some stubs don't push a frame, so we should.
+ // check that we are in the same symbol.
+ if (!InRange())
+ {
+ return true;
+ }
+ }
+ return false;
+}
Modified: lldb/branches/lldb-platform-work/source/Target/ThreadPlanStepUntil.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Target/ThreadPlanStepUntil.cpp?rev=156105&r1=156104&r2=156105&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Target/ThreadPlanStepUntil.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Target/ThreadPlanStepUntil.cpp Thu May 3 16:36:31 2012
@@ -51,12 +51,6 @@
m_until_points (),
m_stop_others (stop_others)
{
-
- // Step until plans can be master plans, since you could hit a breakpoint while stepping to the stop point, step around
- // a bit, then continue to finish up the step until.
- SetIsMasterPlan (true);
- SetOkayToDiscard(true);
-
// Stash away our "until" addresses:
TargetSP target_sp (m_thread.CalculateTarget());
Modified: lldb/branches/lldb-platform-work/tools/debugserver/debugserver.xcodeproj/project.pbxproj
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/tools/debugserver/debugserver.xcodeproj/project.pbxproj?rev=156105&r1=156104&r2=156105&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/tools/debugserver/debugserver.xcodeproj/project.pbxproj (original)
+++ lldb/branches/lldb-platform-work/tools/debugserver/debugserver.xcodeproj/project.pbxproj Thu May 3 16:36:31 2012
@@ -514,10 +514,7 @@
armv7,
armv7s,
);
- "ARCHS[sdk=macosx*]" = (
- x86_64,
- i386,
- );
+ "ARCHS[sdk=macosx*]" = "$(ARCHS_STANDARD_64_BIT)";
CURRENT_PROJECT_VERSION = 186;
DEAD_CODE_STRIPPING = YES;
GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
More information about the lldb-commits
mailing list