diff options
author | Jim Ingham <jingham@apple.com> | 2013-03-13 01:56:41 +0000 |
---|---|---|
committer | Jim Ingham <jingham@apple.com> | 2013-03-13 01:56:41 +0000 |
commit | 0c61dee1b929d1cdf69edfadbae57bd4862b6259 (patch) | |
tree | a91664deb80fc78503e946deea04e294c2ac93c7 /lldb/source/Target/ThreadPlanStepRange.cpp | |
parent | 32ce20c5eed6336feed739a6903b0b6d351030c6 (diff) | |
download | bcm5719-llvm-0c61dee1b929d1cdf69edfadbae57bd4862b6259.tar.gz bcm5719-llvm-0c61dee1b929d1cdf69edfadbae57bd4862b6259.zip |
The step by running from branch to branch pretty much works with this checkin (at least for x86_64) but is still
turned off, it needs more qualification. If you want to play with it, change the initialization of m_use_fast_step
to true.
llvm-svn: 176923
Diffstat (limited to 'lldb/source/Target/ThreadPlanStepRange.cpp')
-rw-r--r-- | lldb/source/Target/ThreadPlanStepRange.cpp | 68 |
1 files changed, 61 insertions, 7 deletions
diff --git a/lldb/source/Target/ThreadPlanStepRange.cpp b/lldb/source/Target/ThreadPlanStepRange.cpp index 912e08769c8..52048064d2c 100644 --- a/lldb/source/Target/ThreadPlanStepRange.cpp +++ b/lldb/source/Target/ThreadPlanStepRange.cpp @@ -15,6 +15,8 @@ // Project includes #include "lldb/lldb-private-log.h" +#include "lldb/Breakpoint/BreakpointLocation.h" +#include "lldb/Breakpoint/BreakpointSite.h" #include "lldb/Core/Disassembler.h" #include "lldb/Core/Log.h" #include "lldb/Core/Stream.h" @@ -49,7 +51,8 @@ ThreadPlanStepRange::ThreadPlanStepRange (ThreadPlanKind kind, m_stop_others (stop_others), m_stack_id (), m_no_more_plans (false), - m_first_run_event (true) + m_first_run_event (true), + m_use_fast_step(false) { AddRange(range); m_stack_id = m_thread.GetStackFrameAtIndex(0)->GetStackID(); @@ -300,6 +303,9 @@ ThreadPlanStepRange::ClearNextBranchBreakpoint() { if (m_next_branch_bp_sp) { + LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP)); + if (log) + log->Printf ("Removing next branch breakpoint: %d.", m_next_branch_bp_sp->GetID()); GetTarget().RemoveBreakpointByID (m_next_branch_bp_sp->GetID()); m_next_branch_bp_sp.reset(); } @@ -308,11 +314,15 @@ ThreadPlanStepRange::ClearNextBranchBreakpoint() bool ThreadPlanStepRange::SetNextBranchBreakpoint () { + if (m_next_branch_bp_sp) + return true; + + LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP)); // Stepping through ranges using breakpoints doesn't work yet, but with this off we fall back to instruction // single stepping. - return false; - // Always clear the next branch breakpoint, we don't want to leave one of these stranded. - ClearNextBranchBreakpoint(); + if (!m_use_fast_step) + return false; + lldb::addr_t cur_addr = GetThread().GetRegisterContext()->GetPC(); // Find the current address in our address ranges, and fetch the disassembly if we haven't already: size_t pc_index; @@ -330,8 +340,9 @@ ThreadPlanStepRange::SetNextBranchBreakpoint () // If we didn't find a branch, run to the end of the range. if (branch_index == UINT32_MAX) { - branch_index = instructions->GetSize() - 2; + branch_index = instructions->GetSize() - 1; } + if (branch_index - pc_index > 1) { const bool is_internal = true; @@ -339,8 +350,26 @@ ThreadPlanStepRange::SetNextBranchBreakpoint () m_next_branch_bp_sp = GetTarget().CreateBreakpoint(run_to_address, is_internal); if (m_next_branch_bp_sp) { + if (log) + { + lldb::break_id_t bp_site_id = LLDB_INVALID_BREAK_ID; + BreakpointLocationSP bp_loc = m_next_branch_bp_sp->GetLocationAtIndex(0); + if (bp_loc) + { + BreakpointSiteSP bp_site = bp_loc->GetBreakpointSite(); + if (bp_site) + { + bp_site_id = bp_site->GetID(); + } + } + log->Printf ("ThreadPlanStepRange::SetNextBranchBreakpoint - Setting breakpoint %d (site %d) to run to address 0x%" PRIx64, + m_next_branch_bp_sp->GetID(), + bp_site_id, + run_to_address.GetLoadAddress(&m_thread.GetProcess()->GetTarget())); + } m_next_branch_bp_sp->SetThreadID(m_thread.GetID()); m_next_branch_bp_sp->SetBreakpointKind ("next-branch-location"); + return true; } else return false; @@ -352,15 +381,39 @@ ThreadPlanStepRange::SetNextBranchBreakpoint () bool ThreadPlanStepRange::NextRangeBreakpointExplainsStop (lldb::StopInfoSP stop_info_sp) { + LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP)); if (!m_next_branch_bp_sp) return false; break_id_t bp_site_id = stop_info_sp->GetValue(); BreakpointSiteSP bp_site_sp = m_thread.GetProcess()->GetBreakpointSiteList().FindByID(bp_site_id); - if (!bp_site_sp->IsBreakpointAtThisSite (m_next_branch_bp_sp->GetID())) + if (!bp_site_sp) + return false; + else if (!bp_site_sp->IsBreakpointAtThisSite (m_next_branch_bp_sp->GetID())) return false; else - return bp_site_sp->GetNumberOfOwners() == 1; + { + // If we've hit the next branch breakpoint, then clear it. + size_t num_owners = bp_site_sp->GetNumberOfOwners(); + bool explains_stop = true; + // If all the owners are internal, then we are probably just stepping over this range from multiple threads, + // or multiple frames, so we want to continue. If one is not internal, then we should not explain the stop, + // and let the user breakpoint handle the stop. + for (size_t i = 0; i < num_owners; i++) + { + if (!bp_site_sp->GetOwnerAtIndex(i)->GetBreakpoint().IsInternal()) + { + explains_stop = false; + break; + } + } + if (log) + log->Printf ("ThreadPlanStepRange::NextRangeBreakpointExplainsStop - Hit next range breakpoint which has %zu owners - explains stop: %u.", + num_owners, + explains_stop); + ClearNextBranchBreakpoint(); + return explains_stop; + } } bool @@ -416,6 +469,7 @@ ThreadPlanStepRange::MischiefManaged () LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP)); if (log) log->Printf("Completed step through range plan."); + ClearNextBranchBreakpoint(); ThreadPlan::MischiefManaged (); return true; } |