diff options
Diffstat (limited to 'lldb/source/Target')
-rw-r--r-- | lldb/source/Target/Thread.cpp | 36 | ||||
-rw-r--r-- | lldb/source/Target/ThreadPlanStepInRange.cpp | 8 | ||||
-rw-r--r-- | lldb/source/Target/ThreadPlanStepInstruction.cpp | 2 | ||||
-rw-r--r-- | lldb/source/Target/ThreadPlanStepOut.cpp | 24 | ||||
-rw-r--r-- | lldb/source/Target/ThreadPlanStepOverRange.cpp | 8 | ||||
-rw-r--r-- | lldb/source/Target/ThreadPlanStepUntil.cpp | 62 |
6 files changed, 86 insertions, 54 deletions
diff --git a/lldb/source/Target/Thread.cpp b/lldb/source/Target/Thread.cpp index 48a11a272ed..2c544a2ca5b 100644 --- a/lldb/source/Target/Thread.cpp +++ b/lldb/source/Target/Thread.cpp @@ -661,7 +661,12 @@ Thread::QueueFundamentalPlan (bool abort_other_plans) } ThreadPlan * -Thread::QueueThreadPlanForStepSingleInstruction (bool step_over, bool abort_other_plans, bool stop_other_threads) +Thread::QueueThreadPlanForStepSingleInstruction +( + bool step_over, + bool abort_other_plans, + bool stop_other_threads +) { ThreadPlanSP thread_plan_sp (new ThreadPlanStepInstruction (*this, step_over, stop_other_threads, eVoteNoOpinion, eVoteNoOpinion)); QueueThreadPlan (thread_plan_sp, abort_other_plans); @@ -706,10 +711,24 @@ Thread::QueueThreadPlanForStepOverBreakpointPlan (bool abort_other_plans) } ThreadPlan * -Thread::QueueThreadPlanForStepOut (bool abort_other_plans, SymbolContext *addr_context, bool first_insn, - bool stop_other_threads, Vote stop_vote, Vote run_vote) +Thread::QueueThreadPlanForStepOut +( + bool abort_other_plans, + SymbolContext *addr_context, + bool first_insn, + bool stop_other_threads, + Vote stop_vote, + Vote run_vote, + uint32_t frame_idx +) { - ThreadPlanSP thread_plan_sp (new ThreadPlanStepOut (*this, addr_context, first_insn, stop_other_threads, stop_vote, run_vote)); + ThreadPlanSP thread_plan_sp (new ThreadPlanStepOut (*this, + addr_context, + first_insn, + stop_other_threads, + stop_vote, + run_vote, + frame_idx)); QueueThreadPlan (thread_plan_sp, abort_other_plans); return thread_plan_sp.get(); } @@ -761,11 +780,12 @@ Thread::QueueThreadPlanForRunToAddress (bool abort_other_plans, ThreadPlan * Thread::QueueThreadPlanForStepUntil (bool abort_other_plans, - lldb::addr_t *address_list, - size_t num_addresses, - bool stop_other_threads) + lldb::addr_t *address_list, + size_t num_addresses, + bool stop_other_threads, + uint32_t frame_idx) { - ThreadPlanSP thread_plan_sp (new ThreadPlanStepUntil (*this, address_list, num_addresses, stop_other_threads)); + 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(); diff --git a/lldb/source/Target/ThreadPlanStepInRange.cpp b/lldb/source/Target/ThreadPlanStepInRange.cpp index 9ee8b5621cb..2930d3d68a3 100644 --- a/lldb/source/Target/ThreadPlanStepInRange.cpp +++ b/lldb/source/Target/ThreadPlanStepInRange.cpp @@ -270,9 +270,13 @@ ThreadPlanStepInRange::DefaultShouldStopHereCallback (ThreadPlan *current_plan, if (should_step_out) { // FIXME: Make sure the ThreadPlanForStepOut does the right thing with inlined functions. - return current_plan->GetThread().QueueThreadPlanForStepOut (false, NULL, true, + return current_plan->GetThread().QueueThreadPlanForStepOut (false, + NULL, + true, current_plan->StopOthers(), - eVoteNo, eVoteNoOpinion); + eVoteNo, + eVoteNoOpinion, + 0); // Frame index } return NULL; diff --git a/lldb/source/Target/ThreadPlanStepInstruction.cpp b/lldb/source/Target/ThreadPlanStepInstruction.cpp index a3dc1a82bad..5d744c458e8 100644 --- a/lldb/source/Target/ThreadPlanStepInstruction.cpp +++ b/lldb/source/Target/ThreadPlanStepInstruction.cpp @@ -129,7 +129,7 @@ ThreadPlanStepInstruction::ShouldStop (Event *event_ptr) s.Address (return_addr, m_thread.GetProcess().GetAddressByteSize()); log->Printf("%s.", s.GetData()); } - m_thread.QueueThreadPlanForStepOut(false, NULL, true, m_stop_other_threads, eVoteNo, eVoteNoOpinion); + m_thread.QueueThreadPlanForStepOut(false, NULL, true, m_stop_other_threads, eVoteNo, eVoteNoOpinion, 0); return false; } else diff --git a/lldb/source/Target/ThreadPlanStepOut.cpp b/lldb/source/Target/ThreadPlanStepOut.cpp index 690a43c74fb..5b343bb3394 100644 --- a/lldb/source/Target/ThreadPlanStepOut.cpp +++ b/lldb/source/Target/ThreadPlanStepOut.cpp @@ -35,7 +35,8 @@ ThreadPlanStepOut::ThreadPlanStepOut bool first_insn, bool stop_others, Vote stop_vote, - Vote run_vote + Vote run_vote, + uint32_t frame_idx ) : ThreadPlan (ThreadPlan::eKindStepOut, "Step out", thread, stop_vote, run_vote), m_step_from_context (context), @@ -50,24 +51,20 @@ ThreadPlanStepOut::ThreadPlanStepOut // Find the return address and set a breakpoint there: // FIXME - can we do this more securely if we know first_insn? - StackFrame *return_frame = m_thread.GetStackFrameAtIndex(1).get(); - if (return_frame) + StackFrameSP return_frame_sp (m_thread.GetStackFrameAtIndex(frame_idx + 1)); + if (return_frame_sp) { // TODO: check for inlined frames and do the right thing... - m_return_addr = return_frame->GetRegisterContext()->GetPC(); + m_return_addr = return_frame_sp->GetRegisterContext()->GetPC(); Breakpoint *return_bp = m_thread.GetProcess().GetTarget().CreateBreakpoint (m_return_addr, true).get(); if (return_bp != NULL) { return_bp->SetThreadID(m_thread.GetID()); m_return_bp_id = return_bp->GetID(); } - else - { - m_return_bp_id = LLDB_INVALID_BREAK_ID; - } } - m_stack_depth = m_thread.GetStackFrameCount(); + m_stack_depth = m_thread.GetStackFrameCount() - frame_idx; } ThreadPlanStepOut::~ThreadPlanStepOut () @@ -116,6 +113,10 @@ ThreadPlanStepOut::PlanExplainsStop () BreakpointSiteSP site_sp (m_thread.GetProcess().GetBreakpointSiteList().FindByID (stop_info_sp->GetValue())); if (site_sp && site_sp->IsBreakpointAtThisSite (m_return_bp_id)) { + const uint32_t num_frames = m_thread.GetStackFrameCount(); + if (m_stack_depth > num_frames); + SetPlanComplete(); + // If there was only one owner, then we're done. But if we also hit some // user breakpoint on our way out, we should mark ourselves as done, but // also not claim to explain the stop, since it is more important to report @@ -124,7 +125,6 @@ ThreadPlanStepOut::PlanExplainsStop () if (site_sp->GetNumberOfOwners() == 1) return true; - SetPlanComplete(); } return false; } @@ -143,9 +143,7 @@ ThreadPlanStepOut::PlanExplainsStop () bool ThreadPlanStepOut::ShouldStop (Event *event_ptr) { - if (IsPlanComplete() - || m_thread.GetRegisterContext()->GetPC() == m_return_addr - || m_stack_depth > m_thread.GetStackFrameCount()) + if (IsPlanComplete() || m_stack_depth > m_thread.GetStackFrameCount()) { SetPlanComplete(); return true; diff --git a/lldb/source/Target/ThreadPlanStepOverRange.cpp b/lldb/source/Target/ThreadPlanStepOverRange.cpp index 5b37290ecb3..2d6f0309b91 100644 --- a/lldb/source/Target/ThreadPlanStepOverRange.cpp +++ b/lldb/source/Target/ThreadPlanStepOverRange.cpp @@ -104,7 +104,13 @@ ThreadPlanStepOverRange::ShouldStop (Event *event_ptr) } else if (FrameIsYounger()) { - new_plan = m_thread.QueueThreadPlanForStepOut (false, NULL, true, stop_others, lldb::eVoteNo, lldb::eVoteNoOpinion); + new_plan = m_thread.QueueThreadPlanForStepOut (false, + NULL, + true, + stop_others, + lldb::eVoteNo, + lldb::eVoteNoOpinion, + 0); } else if (!InSymbol()) { diff --git a/lldb/source/Target/ThreadPlanStepUntil.cpp b/lldb/source/Target/ThreadPlanStepUntil.cpp index 8fca2342ac1..5ad0940f09c 100644 --- a/lldb/source/Target/ThreadPlanStepUntil.cpp +++ b/lldb/source/Target/ThreadPlanStepUntil.cpp @@ -37,7 +37,8 @@ ThreadPlanStepUntil::ThreadPlanStepUntil Thread &thread, lldb::addr_t *address_list, size_t num_addresses, - bool stop_others + bool stop_others, + uint32_t frame_idx ) : ThreadPlan (ThreadPlan::eKindStepUntil, "Step until", thread, eVoteNoOpinion, eVoteNoOpinion), m_stack_depth (0), @@ -56,40 +57,43 @@ ThreadPlanStepUntil::ThreadPlanStepUntil // Stash away our "until" addresses: Target &target = m_thread.GetProcess().GetTarget(); - m_step_from_insn = m_thread.GetRegisterContext()->GetPC(0); - lldb::user_id_t thread_id = m_thread.GetID(); - - // Find the return address and set a breakpoint there: - // FIXME - can we do this more securely if we know first_insn? - - StackFrame *return_frame = m_thread.GetStackFrameAtIndex(1).get(); - // TODO: add inline functionality - m_return_addr = return_frame->GetRegisterContext()->GetPC(); - Breakpoint *return_bp = target.CreateBreakpoint (m_return_addr, true).get(); - if (return_bp != NULL) - { - return_bp->SetThreadID(thread_id); - m_return_bp_id = return_bp->GetID(); - } - else + StackFrameSP frame_sp (m_thread.GetStackFrameAtIndex (frame_idx)); + if (frame_sp) { - m_return_bp_id = LLDB_INVALID_BREAK_ID; - } + m_step_from_insn = frame_sp->GetStackID().GetPC(); + lldb::user_id_t thread_id = m_thread.GetID(); - m_stack_depth = m_thread.GetStackFrameCount(); + // Find the return address and set a breakpoint there: + // FIXME - can we do this more securely if we know first_insn? - // Now set breakpoints on all our return addresses: - for (int i = 0; i < num_addresses; i++) - { - Breakpoint *until_bp = target.CreateBreakpoint (address_list[i], true).get(); - if (until_bp != NULL) + StackFrameSP return_frame_sp (m_thread.GetStackFrameAtIndex(frame_idx + 1)); + if (return_frame_sp) { - until_bp->SetThreadID(thread_id); - m_until_points[address_list[i]] = until_bp->GetID(); + // TODO: add inline functionality + m_return_addr = return_frame_sp->GetStackID().GetPC(); + Breakpoint *return_bp = target.CreateBreakpoint (m_return_addr, true).get(); + if (return_bp != NULL) + { + return_bp->SetThreadID(thread_id); + m_return_bp_id = return_bp->GetID(); + } } - else + + m_stack_depth = m_thread.GetStackFrameCount() - frame_idx; + + // Now set breakpoints on all our return addresses: + for (int i = 0; i < num_addresses; i++) { - m_until_points[address_list[i]] = LLDB_INVALID_BREAK_ID; + Breakpoint *until_bp = target.CreateBreakpoint (address_list[i], true).get(); + if (until_bp != NULL) + { + until_bp->SetThreadID(thread_id); + m_until_points[address_list[i]] = until_bp->GetID(); + } + else + { + m_until_points[address_list[i]] = LLDB_INVALID_BREAK_ID; + } } } } |