summaryrefslogtreecommitdiffstats
path: root/lldb/source/Target
diff options
context:
space:
mode:
Diffstat (limited to 'lldb/source/Target')
-rw-r--r--lldb/source/Target/Thread.cpp36
-rw-r--r--lldb/source/Target/ThreadPlanStepInRange.cpp8
-rw-r--r--lldb/source/Target/ThreadPlanStepInstruction.cpp2
-rw-r--r--lldb/source/Target/ThreadPlanStepOut.cpp24
-rw-r--r--lldb/source/Target/ThreadPlanStepOverRange.cpp8
-rw-r--r--lldb/source/Target/ThreadPlanStepUntil.cpp62
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;
+ }
}
}
}
OpenPOWER on IntegriCloud