From 4d56e9c1cb7c010ed1bccff952fc5c879bd1aba6 Mon Sep 17 00:00:00 2001 From: Jim Ingham Date: Thu, 18 Jul 2013 21:48:26 +0000 Subject: [PATCH] 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. llvm-svn: 186618 --- lldb/include/lldb/Target/Thread.h | 49 +++++++++++++-------- lldb/include/lldb/Target/ThreadPlanBase.h | 2 +- .../include/lldb/Target/ThreadPlanShouldStopHere.h | 2 +- lldb/include/lldb/Target/ThreadPlanStepInRange.h | 7 +-- .../lldb/Target/ThreadPlanStepInstruction.h | 2 +- lldb/include/lldb/Target/ThreadPlanStepOut.h | 2 +- lldb/include/lldb/Target/ThreadPlanStepThrough.h | 2 +- lldb/include/lldb/Target/ThreadPlanStepUntil.h | 2 +- lldb/include/lldb/lldb-private-interfaces.h | 2 +- lldb/source/API/SBThread.cpp | 42 +++++++++--------- lldb/source/Commands/CommandObjectThread.cpp | 34 +++++++-------- .../AppleObjCTrampolineHandler.cpp | 2 +- lldb/source/Target/StopInfo.cpp | 12 +++--- lldb/source/Target/Thread.cpp | 44 +++++++++---------- lldb/source/Target/ThreadPlanShouldStopHere.cpp | 12 +++--- lldb/source/Target/ThreadPlanStepInRange.cpp | 50 ++++++++++++++-------- lldb/source/Target/ThreadPlanStepOverRange.cpp | 18 ++++---- 17 files changed, 156 insertions(+), 128 deletions(-) diff --git a/lldb/include/lldb/Target/Thread.h b/lldb/include/lldb/Target/Thread.h index cc47dc7..e4e532e 100644 --- a/lldb/include/lldb/Target/Thread.h +++ b/lldb/include/lldb/Target/Thread.h @@ -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, diff --git a/lldb/include/lldb/Target/ThreadPlanBase.h b/lldb/include/lldb/Target/ThreadPlanBase.h index 226caea..69959e1 100644 --- a/lldb/include/lldb/Target/ThreadPlanBase.h +++ b/lldb/include/lldb/Target/ThreadPlanBase.h @@ -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); diff --git a/lldb/include/lldb/Target/ThreadPlanShouldStopHere.h b/lldb/include/lldb/Target/ThreadPlanShouldStopHere.h index 02c8cf0b..62068b7 100644 --- a/lldb/include/lldb/Target/ThreadPlanShouldStopHere.h +++ b/lldb/include/lldb/Target/ThreadPlanShouldStopHere.h @@ -53,7 +53,7 @@ public: void SetShouldStopHereCallback (ThreadPlanShouldStopHereCallback callback, void *baton); - ThreadPlan * + lldb::ThreadPlanSP InvokeShouldStopHereCallback (); lldb_private::Flags & diff --git a/lldb/include/lldb/Target/ThreadPlanStepInRange.h b/lldb/include/lldb/Target/ThreadPlanStepInRange.h index 158c860..dbc8446 100644 --- a/lldb/include/lldb/Target/ThreadPlanStepInRange.h +++ b/lldb/include/lldb/Target/ThreadPlanStepInRange.h @@ -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 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. diff --git a/lldb/include/lldb/Target/ThreadPlanStepInstruction.h b/lldb/include/lldb/Target/ThreadPlanStepInstruction.h index 832508d..7f783ff 100644 --- a/lldb/include/lldb/Target/ThreadPlanStepInstruction.h +++ b/lldb/include/lldb/Target/ThreadPlanStepInstruction.h @@ -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; diff --git a/lldb/include/lldb/Target/ThreadPlanStepOut.h b/lldb/include/lldb/Target/ThreadPlanStepOut.h index 918c023..2737978 100644 --- a/lldb/include/lldb/Target/ThreadPlanStepOut.h +++ b/lldb/include/lldb/Target/ThreadPlanStepOut.h @@ -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, diff --git a/lldb/include/lldb/Target/ThreadPlanStepThrough.h b/lldb/include/lldb/Target/ThreadPlanStepThrough.h index 08169d1..1697966 100644 --- a/lldb/include/lldb/Target/ThreadPlanStepThrough.h +++ b/lldb/include/lldb/Target/ThreadPlanStepThrough.h @@ -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); diff --git a/lldb/include/lldb/Target/ThreadPlanStepUntil.h b/lldb/include/lldb/Target/ThreadPlanStepUntil.h index e87d24f..5aa3876 100644 --- a/lldb/include/lldb/Target/ThreadPlanStepUntil.h +++ b/lldb/include/lldb/Target/ThreadPlanStepUntil.h @@ -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, diff --git a/lldb/include/lldb/lldb-private-interfaces.h b/lldb/include/lldb/lldb-private-interfaces.h index 492926e..949cafe 100644 --- a/lldb/include/lldb/lldb-private-interfaces.h +++ b/lldb/include/lldb/lldb-private-interfaces.h @@ -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); diff --git a/lldb/source/API/SBThread.cpp b/lldb/source/API/SBThread.cpp index 431adba..2752620 100644 --- a/lldb/source/API/SBThread.cpp +++ b/lldb/source/API/SBThread.cpp @@ -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 diff --git a/lldb/source/Commands/CommandObjectThread.cpp b/lldb/source/Commands/CommandObjectThread.cpp index 4b123985..b8657b43 100644 --- a/lldb/source/Commands/CommandObjectThread.cpp +++ b/lldb/source/Commands/CommandObjectThread.cpp @@ -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 (new_plan); + ThreadPlanStepInRange *step_in_range_plan = static_cast (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 { diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.cpp b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.cpp index b7c5df2..51fd0d4 100644 --- a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.cpp +++ b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.cpp @@ -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 diff --git a/lldb/source/Target/StopInfo.cpp b/lldb/source/Target/StopInfo.cpp index 23b0b5d..2479368 100644 --- a/lldb/source/Target/StopInfo.cpp +++ b/lldb/source/Target/StopInfo.cpp @@ -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); diff --git a/lldb/source/Target/Thread.cpp b/lldb/source/Target/Thread.cpp index 12ec40f..401eac2 100644 --- a/lldb/source/Target/Thread.cpp +++ b/lldb/source/Target/Thread.cpp @@ -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; } diff --git a/lldb/source/Target/ThreadPlanShouldStopHere.cpp b/lldb/source/Target/ThreadPlanShouldStopHere.cpp index 71543ae..8766234 100644 --- a/lldb/source/Target/ThreadPlanShouldStopHere.cpp +++ b/lldb/source/Target/ThreadPlanShouldStopHere.cpp @@ -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(); } diff --git a/lldb/source/Target/ThreadPlanStepInRange.cpp b/lldb/source/Target/ThreadPlanStepInRange.cpp index b7ebfea..c1f14bd 100644 --- a/lldb/source/Target/ThreadPlanStepInRange.cpp +++ b/lldb/source/Target/ThreadPlanStepInRange.cpp @@ -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 diff --git a/lldb/source/Target/ThreadPlanStepOverRange.cpp b/lldb/source/Target/ThreadPlanStepOverRange.cpp index 679ef46..7b8539c 100644 --- a/lldb/source/Target/ThreadPlanStepOverRange.cpp +++ b/lldb/source/Target/ThreadPlanStepOverRange.cpp @@ -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. -- 2.7.4