forked from OSchip/llvm-project
This commit does two things. One, it converts the return value of the QueueThreadPlanXXX
plan providers from a "ThreadPlan *" to a "lldb::ThreadPlanSP". That was needed to fix a bug where the ThreadPlanStepInRange wasn't checking with its sub-plans to make sure they succeed before trying to proceed further. If the sub-plan failed and as a result didn't make any progress, you could end up retrying the same failing algorithm in an infinite loop. <rdar://problem/14043602> llvm-svn: 186618
This commit is contained in:
parent
5937ec7502
commit
4d56e9c1cb
lldb
include/lldb
Target
Thread.hThreadPlanBase.hThreadPlanShouldStopHere.hThreadPlanStepInRange.hThreadPlanStepInstruction.hThreadPlanStepOut.hThreadPlanStepThrough.hThreadPlanStepUntil.h
lldb-private-interfaces.hsource
API
Commands
Plugins/LanguageRuntime/ObjC/AppleObjCRuntime
Target
|
@ -460,6 +460,19 @@ public:
|
|||
// The idea is that particular Platform plugins can override these methods to
|
||||
// provide the implementation of these basic operations appropriate to their
|
||||
// environment.
|
||||
//
|
||||
// NB: All the QueueThreadPlanXXX providers return Shared Pointers to
|
||||
// Thread plans. This is useful so that you can modify the plans after
|
||||
// creation in ways specific to that plan type. Also, it is often necessary for
|
||||
// ThreadPlans that utilize other ThreadPlans to implement their task to keep a shared
|
||||
// pointer to the sub-plan.
|
||||
// But besides that, the shared pointers should only be held onto by entities who live no longer
|
||||
// than the thread containing the ThreadPlan.
|
||||
// FIXME: If this becomes a problem, we can make a version that just returns a pointer,
|
||||
// which it is clearly unsafe to hold onto, and a shared pointer version, and only allow
|
||||
// ThreadPlan and Co. to use the latter. That is made more annoying to do because there's
|
||||
// no elegant way to friend a method to all sub-classes of a given class.
|
||||
//
|
||||
//------------------------------------------------------------------
|
||||
|
||||
//------------------------------------------------------------------
|
||||
|
@ -474,9 +487,9 @@ public:
|
|||
/// Otherwise this plan will go on the end of the plan stack.
|
||||
///
|
||||
/// @return
|
||||
/// A pointer to the newly queued thread plan, or NULL if the plan could not be queued.
|
||||
/// A shared pointer to the newly queued thread plan, or NULL if the plan could not be queued.
|
||||
//------------------------------------------------------------------
|
||||
virtual ThreadPlan *
|
||||
virtual lldb::ThreadPlanSP
|
||||
QueueFundamentalPlan (bool abort_other_plans);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
|
@ -489,9 +502,9 @@ public:
|
|||
/// Otherwise this plan will go on the end of the plan stack.
|
||||
///
|
||||
/// @return
|
||||
/// A pointer to the newly queued thread plan, or NULL if the plan could not be queued.
|
||||
/// A shared pointer to the newly queued thread plan, or NULL if the plan could not be queued.
|
||||
//------------------------------------------------------------------
|
||||
virtual ThreadPlan *
|
||||
virtual lldb::ThreadPlanSP
|
||||
QueueThreadPlanForStepOverBreakpointPlan (bool abort_other_plans);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
|
@ -508,9 +521,9 @@ public:
|
|||
/// \b true if we will stop other threads while we single step this one.
|
||||
///
|
||||
/// @return
|
||||
/// A pointer to the newly queued thread plan, or NULL if the plan could not be queued.
|
||||
/// A shared pointer to the newly queued thread plan, or NULL if the plan could not be queued.
|
||||
//------------------------------------------------------------------
|
||||
virtual ThreadPlan *
|
||||
virtual lldb::ThreadPlanSP
|
||||
QueueThreadPlanForStepSingleInstruction (bool step_over,
|
||||
bool abort_other_plans,
|
||||
bool stop_other_threads);
|
||||
|
@ -540,9 +553,9 @@ public:
|
|||
/// \b true if we will stop other threads while we single step this one.
|
||||
///
|
||||
/// @return
|
||||
/// A pointer to the newly queued thread plan, or NULL if the plan could not be queued.
|
||||
/// A shared pointer to the newly queued thread plan, or NULL if the plan could not be queued.
|
||||
//------------------------------------------------------------------
|
||||
virtual ThreadPlan *
|
||||
virtual lldb::ThreadPlanSP
|
||||
QueueThreadPlanForStepOverRange (bool abort_other_plans,
|
||||
const AddressRange &range,
|
||||
const SymbolContext &addr_context,
|
||||
|
@ -578,9 +591,9 @@ public:
|
|||
/// If \b true we will step out if we step into code with no debug info.
|
||||
///
|
||||
/// @return
|
||||
/// A pointer to the newly queued thread plan, or NULL if the plan could not be queued.
|
||||
/// A shared pointer to the newly queued thread plan, or NULL if the plan could not be queued.
|
||||
//------------------------------------------------------------------
|
||||
virtual ThreadPlan *
|
||||
virtual lldb::ThreadPlanSP
|
||||
QueueThreadPlanForStepInRange (bool abort_other_plans,
|
||||
const AddressRange &range,
|
||||
const SymbolContext &addr_context,
|
||||
|
@ -614,9 +627,9 @@ public:
|
|||
/// See standard meanings for the stop & run votes in ThreadPlan.h.
|
||||
///
|
||||
/// @return
|
||||
/// A pointer to the newly queued thread plan, or NULL if the plan could not be queued.
|
||||
/// A shared pointer to the newly queued thread plan, or NULL if the plan could not be queued.
|
||||
//------------------------------------------------------------------
|
||||
virtual ThreadPlan *
|
||||
virtual lldb::ThreadPlanSP
|
||||
QueueThreadPlanForStepOut (bool abort_other_plans,
|
||||
SymbolContext *addr_context,
|
||||
bool first_insn,
|
||||
|
@ -642,9 +655,9 @@ public:
|
|||
/// \b true if we will stop other threads while we single step this one.
|
||||
///
|
||||
/// @return
|
||||
/// A pointer to the newly queued thread plan, or NULL if the plan could not be queued.
|
||||
/// A shared pointer to the newly queued thread plan, or NULL if the plan could not be queued.
|
||||
//------------------------------------------------------------------
|
||||
virtual ThreadPlan *
|
||||
virtual lldb::ThreadPlanSP
|
||||
QueueThreadPlanForStepThrough (StackID &return_stack_id,
|
||||
bool abort_other_plans,
|
||||
bool stop_other_threads);
|
||||
|
@ -665,21 +678,21 @@ public:
|
|||
/// \b true if we will stop other threads while we single step this one.
|
||||
///
|
||||
/// @return
|
||||
/// A pointer to the newly queued thread plan, or NULL if the plan could not be queued.
|
||||
/// A shared pointer to the newly queued thread plan, or NULL if the plan could not be queued.
|
||||
//------------------------------------------------------------------
|
||||
virtual ThreadPlan *
|
||||
virtual lldb::ThreadPlanSP
|
||||
QueueThreadPlanForRunToAddress (bool abort_other_plans,
|
||||
Address &target_addr,
|
||||
bool stop_other_threads);
|
||||
|
||||
virtual ThreadPlan *
|
||||
virtual lldb::ThreadPlanSP
|
||||
QueueThreadPlanForStepUntil (bool abort_other_plans,
|
||||
lldb::addr_t *address_list,
|
||||
size_t num_addresses,
|
||||
bool stop_others,
|
||||
uint32_t frame_idx);
|
||||
|
||||
virtual ThreadPlan *
|
||||
virtual lldb::ThreadPlanSP
|
||||
QueueThreadPlanForCallFunction (bool abort_other_plans,
|
||||
Address& function,
|
||||
lldb::addr_t arg,
|
||||
|
|
|
@ -59,7 +59,7 @@ protected:
|
|||
ThreadPlanBase (Thread &thread);
|
||||
|
||||
private:
|
||||
friend ThreadPlan *
|
||||
friend lldb::ThreadPlanSP
|
||||
Thread::QueueFundamentalPlan(bool abort_other_plans);
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN (ThreadPlanBase);
|
||||
|
|
|
@ -53,7 +53,7 @@ public:
|
|||
void
|
||||
SetShouldStopHereCallback (ThreadPlanShouldStopHereCallback callback, void *baton);
|
||||
|
||||
ThreadPlan *
|
||||
lldb::ThreadPlanSP
|
||||
InvokeShouldStopHereCallback ();
|
||||
|
||||
lldb_private::Flags &
|
||||
|
|
|
@ -54,7 +54,7 @@ public:
|
|||
m_step_into_target.SetCString(target);
|
||||
}
|
||||
|
||||
static ThreadPlan *
|
||||
static lldb::ThreadPlanSP
|
||||
DefaultShouldStopHereCallback (ThreadPlan *current_plan, Flags &flags, void *baton);
|
||||
|
||||
static void
|
||||
|
@ -77,12 +77,12 @@ protected:
|
|||
|
||||
private:
|
||||
|
||||
friend ThreadPlan *
|
||||
friend lldb::ThreadPlanSP
|
||||
Thread::QueueThreadPlanForStepOverRange (bool abort_other_plans,
|
||||
const AddressRange &range,
|
||||
const SymbolContext &addr_context,
|
||||
lldb::RunMode stop_others);
|
||||
friend ThreadPlan *
|
||||
friend lldb::ThreadPlanSP
|
||||
Thread::QueueThreadPlanForStepInRange (bool abort_other_plans,
|
||||
const AddressRange &range,
|
||||
const SymbolContext &addr_context,
|
||||
|
@ -95,6 +95,7 @@ private:
|
|||
// from step in.
|
||||
|
||||
static uint32_t s_default_flag_values;
|
||||
lldb::ThreadPlanSP m_sub_plan_sp; // Keep track of the last plan we were running. If it fails, we should stop.
|
||||
std::unique_ptr<RegularExpression> m_avoid_regexp_ap;
|
||||
bool m_step_past_prologue; // FIXME: For now hard-coded to true, we could put a switch in for this if there's
|
||||
// demand for that.
|
||||
|
|
|
@ -43,7 +43,7 @@ protected:
|
|||
Vote run_vote);
|
||||
|
||||
private:
|
||||
friend ThreadPlan *
|
||||
friend lldb::ThreadPlanSP
|
||||
Thread::QueueThreadPlanForStepSingleInstruction (bool step_over, bool abort_other_plans, bool stop_other_threads);
|
||||
|
||||
lldb::addr_t m_instruction_addr;
|
||||
|
|
|
@ -66,7 +66,7 @@ private:
|
|||
Function *m_immediate_step_from_function;
|
||||
lldb::ValueObjectSP m_return_valobj_sp;
|
||||
|
||||
friend ThreadPlan *
|
||||
friend lldb::ThreadPlanSP
|
||||
Thread::QueueThreadPlanForStepOut (bool abort_other_plans,
|
||||
SymbolContext *addr_context,
|
||||
bool first_insn,
|
||||
|
|
|
@ -48,7 +48,7 @@ protected:
|
|||
HitOurBackstopBreakpoint();
|
||||
|
||||
private:
|
||||
friend ThreadPlan *
|
||||
friend lldb::ThreadPlanSP
|
||||
Thread::QueueThreadPlanForStepThrough (StackID &return_stack_id,
|
||||
bool abort_other_plans,
|
||||
bool stop_others);
|
||||
|
|
|
@ -61,7 +61,7 @@ private:
|
|||
|
||||
void Clear();
|
||||
|
||||
friend ThreadPlan *
|
||||
friend lldb::ThreadPlanSP
|
||||
Thread::QueueThreadPlanForStepUntil (bool abort_other_plans,
|
||||
lldb::addr_t *address_list,
|
||||
size_t num_addresses,
|
||||
|
|
|
@ -33,7 +33,7 @@ namespace lldb_private
|
|||
typedef SymbolVendor* (*SymbolVendorCreateInstance) (const lldb::ModuleSP &module_sp, lldb_private::Stream *feedback_strm); // Module can be NULL for default system symbol vendor
|
||||
typedef bool (*BreakpointHitCallback) (void *baton, StoppointCallbackContext *context, lldb::user_id_t break_id, lldb::user_id_t break_loc_id);
|
||||
typedef bool (*WatchpointHitCallback) (void *baton, StoppointCallbackContext *context, lldb::user_id_t watch_id);
|
||||
typedef ThreadPlan * (*ThreadPlanShouldStopHereCallback) (ThreadPlan *current_plan, Flags &flags, void *baton);
|
||||
typedef lldb::ThreadPlanSP (*ThreadPlanShouldStopHereCallback) (ThreadPlan *current_plan, Flags &flags, void *baton);
|
||||
typedef UnwindAssembly* (*UnwindAssemblyCreateInstance) (const ArchSpec &arch);
|
||||
typedef int (*ComparisonFunction)(const void *, const void *);
|
||||
typedef bool (*CommandOverrideCallback)(void *baton, const char **argv);
|
||||
|
|
|
@ -567,28 +567,28 @@ SBThread::StepOver (lldb::RunMode stop_other_threads)
|
|||
Thread *thread = exe_ctx.GetThreadPtr();
|
||||
bool abort_other_plans = false;
|
||||
StackFrameSP frame_sp(thread->GetStackFrameAtIndex (0));
|
||||
ThreadPlan *new_plan = NULL;
|
||||
|
||||
ThreadPlanSP new_plan_sp;
|
||||
if (frame_sp)
|
||||
{
|
||||
if (frame_sp->HasDebugInformation ())
|
||||
{
|
||||
SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything));
|
||||
new_plan = thread->QueueThreadPlanForStepOverRange (abort_other_plans,
|
||||
new_plan_sp = thread->QueueThreadPlanForStepOverRange (abort_other_plans,
|
||||
sc.line_entry.range,
|
||||
sc,
|
||||
stop_other_threads);
|
||||
}
|
||||
else
|
||||
{
|
||||
new_plan = thread->QueueThreadPlanForStepSingleInstruction (true,
|
||||
new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction (true,
|
||||
abort_other_plans,
|
||||
stop_other_threads);
|
||||
}
|
||||
}
|
||||
|
||||
// This returns an error, we should use it!
|
||||
ResumeNewPlan (exe_ctx, new_plan);
|
||||
ResumeNewPlan (exe_ctx, new_plan_sp.get());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -618,13 +618,13 @@ SBThread::StepInto (const char *target_name, lldb::RunMode stop_other_threads)
|
|||
|
||||
Thread *thread = exe_ctx.GetThreadPtr();
|
||||
StackFrameSP frame_sp(thread->GetStackFrameAtIndex (0));
|
||||
ThreadPlan *new_plan = NULL;
|
||||
ThreadPlanSP new_plan_sp;
|
||||
|
||||
if (frame_sp && frame_sp->HasDebugInformation ())
|
||||
{
|
||||
bool avoid_code_without_debug_info = true;
|
||||
SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything));
|
||||
new_plan = thread->QueueThreadPlanForStepInRange (abort_other_plans,
|
||||
new_plan_sp = thread->QueueThreadPlanForStepInRange (abort_other_plans,
|
||||
sc.line_entry.range,
|
||||
sc,
|
||||
target_name,
|
||||
|
@ -633,13 +633,13 @@ SBThread::StepInto (const char *target_name, lldb::RunMode stop_other_threads)
|
|||
}
|
||||
else
|
||||
{
|
||||
new_plan = thread->QueueThreadPlanForStepSingleInstruction (false,
|
||||
new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction (false,
|
||||
abort_other_plans,
|
||||
stop_other_threads);
|
||||
}
|
||||
|
||||
// This returns an error, we should use it!
|
||||
ResumeNewPlan (exe_ctx, new_plan);
|
||||
ResumeNewPlan (exe_ctx, new_plan_sp.get());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -662,16 +662,16 @@ SBThread::StepOut ()
|
|||
|
||||
Thread *thread = exe_ctx.GetThreadPtr();
|
||||
|
||||
ThreadPlan *new_plan = thread->QueueThreadPlanForStepOut (abort_other_plans,
|
||||
ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepOut (abort_other_plans,
|
||||
NULL,
|
||||
false,
|
||||
stop_other_threads,
|
||||
eVoteYes,
|
||||
eVoteNoOpinion,
|
||||
0);
|
||||
0));
|
||||
|
||||
// This returns an error, we should use it!
|
||||
ResumeNewPlan (exe_ctx, new_plan);
|
||||
ResumeNewPlan (exe_ctx, new_plan_sp.get());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -697,16 +697,16 @@ SBThread::StepOutOfFrame (lldb::SBFrame &sb_frame)
|
|||
bool stop_other_threads = false;
|
||||
Thread *thread = exe_ctx.GetThreadPtr();
|
||||
|
||||
ThreadPlan *new_plan = thread->QueueThreadPlanForStepOut (abort_other_plans,
|
||||
ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepOut (abort_other_plans,
|
||||
NULL,
|
||||
false,
|
||||
stop_other_threads,
|
||||
eVoteYes,
|
||||
eVoteNoOpinion,
|
||||
frame_sp->GetFrameIndex());
|
||||
frame_sp->GetFrameIndex()));
|
||||
|
||||
// This returns an error, we should use it!
|
||||
ResumeNewPlan (exe_ctx, new_plan);
|
||||
ResumeNewPlan (exe_ctx, new_plan_sp.get());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -726,10 +726,10 @@ SBThread::StepInstruction (bool step_over)
|
|||
if (exe_ctx.HasThreadScope())
|
||||
{
|
||||
Thread *thread = exe_ctx.GetThreadPtr();
|
||||
ThreadPlan *new_plan = thread->QueueThreadPlanForStepSingleInstruction (step_over, true, true);
|
||||
ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepSingleInstruction (step_over, true, true));
|
||||
|
||||
// This returns an error, we should use it!
|
||||
ResumeNewPlan (exe_ctx, new_plan);
|
||||
ResumeNewPlan (exe_ctx, new_plan_sp.get());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -754,10 +754,10 @@ SBThread::RunToAddress (lldb::addr_t addr)
|
|||
|
||||
Thread *thread = exe_ctx.GetThreadPtr();
|
||||
|
||||
ThreadPlan *new_plan = thread->QueueThreadPlanForRunToAddress (abort_other_plans, target_addr, stop_other_threads);
|
||||
ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForRunToAddress (abort_other_plans, target_addr, stop_other_threads));
|
||||
|
||||
// This returns an error, we should use it!
|
||||
ResumeNewPlan (exe_ctx, new_plan);
|
||||
ResumeNewPlan (exe_ctx, new_plan_sp.get());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -893,13 +893,13 @@ SBThread::StepOverUntil (lldb::SBFrame &sb_frame,
|
|||
}
|
||||
else
|
||||
{
|
||||
ThreadPlan *new_plan = thread->QueueThreadPlanForStepUntil (abort_other_plans,
|
||||
ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepUntil (abort_other_plans,
|
||||
&step_over_until_addrs[0],
|
||||
step_over_until_addrs.size(),
|
||||
stop_other_threads,
|
||||
frame_sp->GetFrameIndex());
|
||||
frame_sp->GetFrameIndex()));
|
||||
|
||||
sb_error = ResumeNewPlan (exe_ctx, new_plan);
|
||||
sb_error = ResumeNewPlan (exe_ctx, new_plan_sp.get());
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
|
@ -461,7 +461,7 @@ protected:
|
|||
else
|
||||
bool_stop_other_threads = true;
|
||||
|
||||
ThreadPlan *new_plan = NULL;
|
||||
ThreadPlanSP new_plan_sp;
|
||||
|
||||
if (m_step_type == eStepTypeInto)
|
||||
{
|
||||
|
@ -469,20 +469,20 @@ protected:
|
|||
|
||||
if (frame->HasDebugInformation ())
|
||||
{
|
||||
new_plan = thread->QueueThreadPlanForStepInRange (abort_other_plans,
|
||||
new_plan_sp = thread->QueueThreadPlanForStepInRange (abort_other_plans,
|
||||
frame->GetSymbolContext(eSymbolContextEverything).line_entry.range,
|
||||
frame->GetSymbolContext(eSymbolContextEverything),
|
||||
m_options.m_step_in_target.c_str(),
|
||||
stop_other_threads,
|
||||
m_options.m_avoid_no_debug);
|
||||
if (new_plan && !m_options.m_avoid_regexp.empty())
|
||||
if (new_plan_sp && !m_options.m_avoid_regexp.empty())
|
||||
{
|
||||
ThreadPlanStepInRange *step_in_range_plan = static_cast<ThreadPlanStepInRange *> (new_plan);
|
||||
ThreadPlanStepInRange *step_in_range_plan = static_cast<ThreadPlanStepInRange *> (new_plan_sp.get());
|
||||
step_in_range_plan->SetAvoidRegexp(m_options.m_avoid_regexp.c_str());
|
||||
}
|
||||
}
|
||||
else
|
||||
new_plan = thread->QueueThreadPlanForStepSingleInstruction (false, abort_other_plans, bool_stop_other_threads);
|
||||
new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction (false, abort_other_plans, bool_stop_other_threads);
|
||||
|
||||
}
|
||||
else if (m_step_type == eStepTypeOver)
|
||||
|
@ -490,27 +490,27 @@ protected:
|
|||
StackFrame *frame = thread->GetStackFrameAtIndex(0).get();
|
||||
|
||||
if (frame->HasDebugInformation())
|
||||
new_plan = thread->QueueThreadPlanForStepOverRange (abort_other_plans,
|
||||
new_plan_sp = thread->QueueThreadPlanForStepOverRange (abort_other_plans,
|
||||
frame->GetSymbolContext(eSymbolContextEverything).line_entry.range,
|
||||
frame->GetSymbolContext(eSymbolContextEverything),
|
||||
stop_other_threads);
|
||||
else
|
||||
new_plan = thread->QueueThreadPlanForStepSingleInstruction (true,
|
||||
new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction (true,
|
||||
abort_other_plans,
|
||||
bool_stop_other_threads);
|
||||
|
||||
}
|
||||
else if (m_step_type == eStepTypeTrace)
|
||||
{
|
||||
new_plan = thread->QueueThreadPlanForStepSingleInstruction (false, abort_other_plans, bool_stop_other_threads);
|
||||
new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction (false, abort_other_plans, bool_stop_other_threads);
|
||||
}
|
||||
else if (m_step_type == eStepTypeTraceOver)
|
||||
{
|
||||
new_plan = thread->QueueThreadPlanForStepSingleInstruction (true, abort_other_plans, bool_stop_other_threads);
|
||||
new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction (true, abort_other_plans, bool_stop_other_threads);
|
||||
}
|
||||
else if (m_step_type == eStepTypeOut)
|
||||
{
|
||||
new_plan = thread->QueueThreadPlanForStepOut (abort_other_plans,
|
||||
new_plan_sp = thread->QueueThreadPlanForStepOut (abort_other_plans,
|
||||
NULL,
|
||||
false,
|
||||
bool_stop_other_threads,
|
||||
|
@ -528,10 +528,10 @@ protected:
|
|||
// 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)
|
||||
if (new_plan_sp)
|
||||
{
|
||||
new_plan->SetIsMasterPlan (true);
|
||||
new_plan->SetOkayToDiscard (false);
|
||||
new_plan_sp->SetIsMasterPlan (true);
|
||||
new_plan_sp->SetOkayToDiscard (false);
|
||||
|
||||
process->GetThreadList().SetSelectedThreadByID (thread->GetID());
|
||||
process->Resume ();
|
||||
|
@ -1001,7 +1001,7 @@ protected:
|
|||
return false;
|
||||
}
|
||||
|
||||
ThreadPlan *new_plan = NULL;
|
||||
ThreadPlanSP new_plan_sp;
|
||||
|
||||
if (frame->HasDebugInformation ())
|
||||
{
|
||||
|
@ -1064,7 +1064,7 @@ protected:
|
|||
return false;
|
||||
}
|
||||
|
||||
new_plan = thread->QueueThreadPlanForStepUntil (abort_other_plans,
|
||||
new_plan_sp = thread->QueueThreadPlanForStepUntil (abort_other_plans,
|
||||
&address_list.front(),
|
||||
address_list.size(),
|
||||
m_options.m_stop_others,
|
||||
|
@ -1072,8 +1072,8 @@ protected:
|
|||
// 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);
|
||||
new_plan_sp->SetIsMasterPlan (true);
|
||||
new_plan_sp->SetOkayToDiscard(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -926,7 +926,7 @@ AppleObjCTrampolineHandler::GetStepThroughDispatchPlan (Thread &thread, bool sto
|
|||
log->Printf("Asked to step to dispatch to nil object, returning empty plan.");
|
||||
return ret_plan_sp;
|
||||
}
|
||||
|
||||
|
||||
ExecutionContext exe_ctx (thread.shared_from_this());
|
||||
Process *process = exe_ctx.GetProcessPtr();
|
||||
// isa_addr will store the class pointer that the method is being dispatched to - so either the class
|
||||
|
|
|
@ -670,12 +670,12 @@ protected:
|
|||
StopInfoSP stored_stop_info_sp = thread_sp->GetStopInfo();
|
||||
assert (stored_stop_info_sp.get() == this);
|
||||
|
||||
ThreadPlan *new_plan = thread_sp->QueueThreadPlanForStepSingleInstruction(false, // step-over
|
||||
false, // abort_other_plans
|
||||
true); // stop_other_threads
|
||||
new_plan->SetIsMasterPlan (true);
|
||||
new_plan->SetOkayToDiscard (false);
|
||||
new_plan->SetPrivate (true);
|
||||
ThreadPlanSP new_plan_sp(thread_sp->QueueThreadPlanForStepSingleInstruction(false, // step-over
|
||||
false, // abort_other_plans
|
||||
true)); // stop_other_threads
|
||||
new_plan_sp->SetIsMasterPlan (true);
|
||||
new_plan_sp->SetOkayToDiscard (false);
|
||||
new_plan_sp->SetPrivate (true);
|
||||
process->GetThreadList().SetSelectedThreadByID (thread_sp->GetID());
|
||||
process->Resume ();
|
||||
process->WaitForProcessToStop (NULL);
|
||||
|
|
|
@ -1337,15 +1337,15 @@ Thread::UnwindInnermostExpression()
|
|||
}
|
||||
|
||||
|
||||
ThreadPlan *
|
||||
ThreadPlanSP
|
||||
Thread::QueueFundamentalPlan (bool abort_other_plans)
|
||||
{
|
||||
ThreadPlanSP thread_plan_sp (new ThreadPlanBase(*this));
|
||||
QueueThreadPlan (thread_plan_sp, abort_other_plans);
|
||||
return thread_plan_sp.get();
|
||||
return thread_plan_sp;
|
||||
}
|
||||
|
||||
ThreadPlan *
|
||||
ThreadPlanSP
|
||||
Thread::QueueThreadPlanForStepSingleInstruction
|
||||
(
|
||||
bool step_over,
|
||||
|
@ -1355,10 +1355,10 @@ Thread::QueueThreadPlanForStepSingleInstruction
|
|||
{
|
||||
ThreadPlanSP thread_plan_sp (new ThreadPlanStepInstruction (*this, step_over, stop_other_threads, eVoteNoOpinion, eVoteNoOpinion));
|
||||
QueueThreadPlan (thread_plan_sp, abort_other_plans);
|
||||
return thread_plan_sp.get();
|
||||
return thread_plan_sp;
|
||||
}
|
||||
|
||||
ThreadPlan *
|
||||
ThreadPlanSP
|
||||
Thread::QueueThreadPlanForStepOverRange
|
||||
(
|
||||
bool abort_other_plans,
|
||||
|
@ -1371,10 +1371,10 @@ Thread::QueueThreadPlanForStepOverRange
|
|||
thread_plan_sp.reset (new ThreadPlanStepOverRange (*this, range, addr_context, stop_other_threads));
|
||||
|
||||
QueueThreadPlan (thread_plan_sp, abort_other_plans);
|
||||
return thread_plan_sp.get();
|
||||
return thread_plan_sp;
|
||||
}
|
||||
|
||||
ThreadPlan *
|
||||
ThreadPlanSP
|
||||
Thread::QueueThreadPlanForStepInRange
|
||||
(
|
||||
bool abort_other_plans,
|
||||
|
@ -1396,19 +1396,19 @@ Thread::QueueThreadPlanForStepInRange
|
|||
thread_plan_sp.reset (plan);
|
||||
|
||||
QueueThreadPlan (thread_plan_sp, abort_other_plans);
|
||||
return thread_plan_sp.get();
|
||||
return thread_plan_sp;
|
||||
}
|
||||
|
||||
|
||||
ThreadPlan *
|
||||
ThreadPlanSP
|
||||
Thread::QueueThreadPlanForStepOverBreakpointPlan (bool abort_other_plans)
|
||||
{
|
||||
ThreadPlanSP thread_plan_sp (new ThreadPlanStepOverBreakpoint (*this));
|
||||
QueueThreadPlan (thread_plan_sp, abort_other_plans);
|
||||
return thread_plan_sp.get();
|
||||
return thread_plan_sp;
|
||||
}
|
||||
|
||||
ThreadPlan *
|
||||
ThreadPlanSP
|
||||
Thread::QueueThreadPlanForStepOut
|
||||
(
|
||||
bool abort_other_plans,
|
||||
|
@ -1431,26 +1431,26 @@ Thread::QueueThreadPlanForStepOut
|
|||
if (thread_plan_sp->ValidatePlan(NULL))
|
||||
{
|
||||
QueueThreadPlan (thread_plan_sp, abort_other_plans);
|
||||
return thread_plan_sp.get();
|
||||
return thread_plan_sp;
|
||||
}
|
||||
else
|
||||
{
|
||||
return NULL;
|
||||
return ThreadPlanSP();
|
||||
}
|
||||
}
|
||||
|
||||
ThreadPlan *
|
||||
ThreadPlanSP
|
||||
Thread::QueueThreadPlanForStepThrough (StackID &return_stack_id, bool abort_other_plans, bool stop_other_threads)
|
||||
{
|
||||
ThreadPlanSP thread_plan_sp(new ThreadPlanStepThrough (*this, return_stack_id, stop_other_threads));
|
||||
if (!thread_plan_sp || !thread_plan_sp->ValidatePlan (NULL))
|
||||
return NULL;
|
||||
return ThreadPlanSP();
|
||||
|
||||
QueueThreadPlan (thread_plan_sp, abort_other_plans);
|
||||
return thread_plan_sp.get();
|
||||
return thread_plan_sp;
|
||||
}
|
||||
|
||||
ThreadPlan *
|
||||
ThreadPlanSP
|
||||
Thread::QueueThreadPlanForCallFunction (bool abort_other_plans,
|
||||
Address& function,
|
||||
lldb::addr_t arg,
|
||||
|
@ -1466,20 +1466,20 @@ Thread::QueueThreadPlanForCallFunction (bool abort_other_plans,
|
|||
unwind_on_error,
|
||||
ignore_breakpoints));
|
||||
QueueThreadPlan (thread_plan_sp, abort_other_plans);
|
||||
return thread_plan_sp.get();
|
||||
return thread_plan_sp;
|
||||
}
|
||||
|
||||
ThreadPlan *
|
||||
ThreadPlanSP
|
||||
Thread::QueueThreadPlanForRunToAddress (bool abort_other_plans,
|
||||
Address &target_addr,
|
||||
bool stop_other_threads)
|
||||
{
|
||||
ThreadPlanSP thread_plan_sp (new ThreadPlanRunToAddress (*this, target_addr, stop_other_threads));
|
||||
QueueThreadPlan (thread_plan_sp, abort_other_plans);
|
||||
return thread_plan_sp.get();
|
||||
return thread_plan_sp;
|
||||
}
|
||||
|
||||
ThreadPlan *
|
||||
ThreadPlanSP
|
||||
Thread::QueueThreadPlanForStepUntil (bool abort_other_plans,
|
||||
lldb::addr_t *address_list,
|
||||
size_t num_addresses,
|
||||
|
@ -1488,7 +1488,7 @@ Thread::QueueThreadPlanForStepUntil (bool abort_other_plans,
|
|||
{
|
||||
ThreadPlanSP thread_plan_sp (new ThreadPlanStepUntil (*this, address_list, num_addresses, stop_other_threads, frame_idx));
|
||||
QueueThreadPlan (thread_plan_sp, abort_other_plans);
|
||||
return thread_plan_sp.get();
|
||||
return thread_plan_sp;
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -45,21 +45,21 @@ ThreadPlanShouldStopHere::SetShouldStopHereCallback (ThreadPlanShouldStopHereCal
|
|||
m_baton = baton;
|
||||
}
|
||||
|
||||
ThreadPlan *
|
||||
ThreadPlanSP
|
||||
ThreadPlanShouldStopHere::InvokeShouldStopHereCallback ()
|
||||
{
|
||||
if (m_callback)
|
||||
{
|
||||
ThreadPlan *return_plan = m_callback (m_owner, m_flags, m_baton);
|
||||
ThreadPlanSP return_plan_sp(m_callback (m_owner, m_flags, m_baton));
|
||||
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
|
||||
if (log)
|
||||
{
|
||||
lldb::addr_t current_addr = m_owner->GetThread().GetRegisterContext()->GetPC(0);
|
||||
|
||||
if (return_plan)
|
||||
if (return_plan_sp)
|
||||
{
|
||||
StreamString s;
|
||||
return_plan->GetDescription (&s, lldb::eDescriptionLevelFull);
|
||||
return_plan_sp->GetDescription (&s, lldb::eDescriptionLevelFull);
|
||||
log->Printf ("ShouldStopHere callback found a step out plan from 0x%" PRIx64 ": %s.", current_addr, s.GetData());
|
||||
}
|
||||
else
|
||||
|
@ -67,8 +67,8 @@ ThreadPlanShouldStopHere::InvokeShouldStopHereCallback ()
|
|||
log->Printf ("ShouldStopHere callback didn't find a step out plan from: 0x%" PRIx64 ".", current_addr);
|
||||
}
|
||||
}
|
||||
return return_plan;
|
||||
return return_plan_sp;
|
||||
}
|
||||
else
|
||||
return NULL;
|
||||
return ThreadPlanSP();
|
||||
}
|
||||
|
|
|
@ -82,7 +82,11 @@ ThreadPlanStepInRange::GetDescription (Stream *s, lldb::DescriptionLevel level)
|
|||
{
|
||||
s->Printf ("Stepping through range (stepping into functions): ");
|
||||
DumpRanges(s);
|
||||
s->Printf ("targeting %s.", m_step_into_target.AsCString());
|
||||
const char *step_into_target = m_step_into_target.AsCString();
|
||||
if (step_into_target && step_into_target[0] != '\0')
|
||||
s->Printf (" targeting %s.", m_step_into_target.AsCString());
|
||||
else
|
||||
s->PutChar('.');
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -90,7 +94,6 @@ bool
|
|||
ThreadPlanStepInRange::ShouldStop (Event *event_ptr)
|
||||
{
|
||||
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
|
||||
m_no_more_plans = false;
|
||||
|
||||
if (log)
|
||||
{
|
||||
|
@ -103,13 +106,24 @@ ThreadPlanStepInRange::ShouldStop (Event *event_ptr)
|
|||
if (IsPlanComplete())
|
||||
return true;
|
||||
|
||||
ThreadPlan* new_plan = NULL;
|
||||
|
||||
m_no_more_plans = false;
|
||||
if (m_sub_plan_sp && m_sub_plan_sp->IsPlanComplete())
|
||||
{
|
||||
if (!m_sub_plan_sp->PlanSucceeded())
|
||||
{
|
||||
SetPlanComplete();
|
||||
m_no_more_plans = true;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
m_sub_plan_sp.reset();
|
||||
}
|
||||
|
||||
if (m_virtual_step)
|
||||
{
|
||||
// If we've just completed a virtual step, all we need to do is check for a ShouldStopHere plan, and otherwise
|
||||
// we're done.
|
||||
new_plan = InvokeShouldStopHereCallback();
|
||||
m_sub_plan_sp = InvokeShouldStopHereCallback();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -131,8 +145,8 @@ ThreadPlanStepInRange::ShouldStop (Event *event_ptr)
|
|||
// A caveat to this is if we think the frame is older but we're actually in a trampoline.
|
||||
// I'm going to make the assumption that you wouldn't RETURN to a trampoline. So if we are
|
||||
// in a trampoline we think the frame is older because the trampoline confused the backtracer.
|
||||
new_plan = m_thread.QueueThreadPlanForStepThrough (m_stack_id, false, stop_others);
|
||||
if (new_plan == NULL)
|
||||
m_sub_plan_sp = m_thread.QueueThreadPlanForStepThrough (m_stack_id, false, stop_others);
|
||||
if (!m_sub_plan_sp)
|
||||
return true;
|
||||
else if (log)
|
||||
{
|
||||
|
@ -167,26 +181,26 @@ ThreadPlanStepInRange::ShouldStop (Event *event_ptr)
|
|||
|
||||
// We may have set the plan up above in the FrameIsOlder section:
|
||||
|
||||
if (new_plan == NULL)
|
||||
new_plan = m_thread.QueueThreadPlanForStepThrough (m_stack_id, false, stop_others);
|
||||
if (!m_sub_plan_sp)
|
||||
m_sub_plan_sp = m_thread.QueueThreadPlanForStepThrough (m_stack_id, false, stop_others);
|
||||
|
||||
if (log)
|
||||
{
|
||||
if (new_plan != NULL)
|
||||
log->Printf ("Found a step through plan: %s", new_plan->GetName());
|
||||
if (m_sub_plan_sp)
|
||||
log->Printf ("Found a step through plan: %s", m_sub_plan_sp->GetName());
|
||||
else
|
||||
log->Printf ("No step through plan found.");
|
||||
}
|
||||
|
||||
// If not, give the "should_stop" callback a chance to push a plan to get us out of here.
|
||||
// But only do that if we actually have stepped in.
|
||||
if (!new_plan && frame_order == eFrameCompareYounger)
|
||||
new_plan = InvokeShouldStopHereCallback();
|
||||
if (!m_sub_plan_sp && frame_order == eFrameCompareYounger)
|
||||
m_sub_plan_sp = InvokeShouldStopHereCallback();
|
||||
|
||||
// If we've stepped in and we are going to stop here, check to see if we were asked to
|
||||
// run past the prologue, and if so do that.
|
||||
|
||||
if (new_plan == NULL && frame_order == eFrameCompareYounger && m_step_past_prologue)
|
||||
if (!m_sub_plan_sp && frame_order == eFrameCompareYounger && m_step_past_prologue)
|
||||
{
|
||||
lldb::StackFrameSP curr_frame = m_thread.GetStackFrameAtIndex(0);
|
||||
if (curr_frame)
|
||||
|
@ -217,13 +231,13 @@ ThreadPlanStepInRange::ShouldStop (Event *event_ptr)
|
|||
if (log)
|
||||
log->Printf ("Pushing past prologue ");
|
||||
|
||||
new_plan = m_thread.QueueThreadPlanForRunToAddress(false, func_start_address,true);
|
||||
m_sub_plan_sp = m_thread.QueueThreadPlanForRunToAddress(false, func_start_address,true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (new_plan == NULL)
|
||||
if (!m_sub_plan_sp)
|
||||
{
|
||||
m_no_more_plans = true;
|
||||
SetPlanComplete();
|
||||
|
@ -303,7 +317,7 @@ ThreadPlanStepInRange::FrameMatchesAvoidRegexp ()
|
|||
return false;
|
||||
}
|
||||
|
||||
ThreadPlan *
|
||||
ThreadPlanSP
|
||||
ThreadPlanStepInRange::DefaultShouldStopHereCallback (ThreadPlan *current_plan, Flags &flags, void *baton)
|
||||
{
|
||||
bool should_step_out = false;
|
||||
|
@ -375,7 +389,7 @@ ThreadPlanStepInRange::DefaultShouldStopHereCallback (ThreadPlan *current_plan,
|
|||
0); // Frame index
|
||||
}
|
||||
|
||||
return NULL;
|
||||
return ThreadPlanSP();
|
||||
}
|
||||
|
||||
bool
|
||||
|
|
|
@ -87,7 +87,7 @@ ThreadPlanStepOverRange::ShouldStop (Event *event_ptr)
|
|||
else
|
||||
stop_others = false;
|
||||
|
||||
ThreadPlan* new_plan = NULL;
|
||||
ThreadPlanSP new_plan_sp;
|
||||
|
||||
FrameComparison frame_order = CompareCurrentFrameToStartFrame();
|
||||
|
||||
|
@ -100,9 +100,9 @@ ThreadPlanStepOverRange::ShouldStop (Event *event_ptr)
|
|||
// in a trampoline we think the frame is older because the trampoline confused the backtracer.
|
||||
// As below, we step through first, and then try to figure out how to get back out again.
|
||||
|
||||
new_plan = m_thread.QueueThreadPlanForStepThrough (m_stack_id, false, stop_others);
|
||||
new_plan_sp = m_thread.QueueThreadPlanForStepThrough (m_stack_id, false, stop_others);
|
||||
|
||||
if (new_plan != NULL && log)
|
||||
if (new_plan_sp && log)
|
||||
log->Printf("Thought I stepped out, but in fact arrived at a trampoline.");
|
||||
}
|
||||
else if (frame_order == eFrameCompareYounger)
|
||||
|
@ -142,7 +142,7 @@ ThreadPlanStepOverRange::ShouldStop (Event *event_ptr)
|
|||
|
||||
if (older_ctx_is_equivalent)
|
||||
{
|
||||
new_plan = m_thread.QueueThreadPlanForStepOut (false,
|
||||
new_plan_sp = m_thread.QueueThreadPlanForStepOut (false,
|
||||
NULL,
|
||||
true,
|
||||
stop_others,
|
||||
|
@ -152,7 +152,7 @@ ThreadPlanStepOverRange::ShouldStop (Event *event_ptr)
|
|||
}
|
||||
else
|
||||
{
|
||||
new_plan = m_thread.QueueThreadPlanForStepThrough (m_stack_id, false, stop_others);
|
||||
new_plan_sp = m_thread.QueueThreadPlanForStepThrough (m_stack_id, false, stop_others);
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -173,7 +173,7 @@ ThreadPlanStepOverRange::ShouldStop (Event *event_ptr)
|
|||
// in which case we need to get out of there. But if we are in a stub then it's
|
||||
// likely going to be hard to get out from here. It is probably easiest to step into the
|
||||
// stub, and then it will be straight-forward to step out.
|
||||
new_plan = m_thread.QueueThreadPlanForStepThrough (m_stack_id, false, stop_others);
|
||||
new_plan_sp = m_thread.QueueThreadPlanForStepThrough (m_stack_id, false, stop_others);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -254,7 +254,7 @@ ThreadPlanStepOverRange::ShouldStop (Event *event_ptr)
|
|||
{
|
||||
const bool abort_other_plans = false;
|
||||
const bool stop_other_threads = false;
|
||||
new_plan = m_thread.QueueThreadPlanForRunToAddress(abort_other_plans,
|
||||
new_plan_sp = m_thread.QueueThreadPlanForRunToAddress(abort_other_plans,
|
||||
next_line_address,
|
||||
stop_other_threads);
|
||||
break;
|
||||
|
@ -273,12 +273,12 @@ ThreadPlanStepOverRange::ShouldStop (Event *event_ptr)
|
|||
// If we get to this point, we're not going to use a previously set "next branch" breakpoint, so delete it:
|
||||
ClearNextBranchBreakpoint();
|
||||
|
||||
if (new_plan == NULL)
|
||||
if (!new_plan_sp)
|
||||
m_no_more_plans = true;
|
||||
else
|
||||
m_no_more_plans = false;
|
||||
|
||||
if (new_plan == NULL)
|
||||
if (!new_plan_sp)
|
||||
{
|
||||
// For efficiencies sake, we know we're done here so we don't have to do this
|
||||
// calculation again in MischiefManaged.
|
||||
|
|
Loading…
Reference in New Issue