From e103ae92ef2336854587778bd3ae88a87e409a5e Mon Sep 17 00:00:00 2001 From: Jonas Devlieghere Date: Thu, 15 Nov 2018 01:18:15 +0000 Subject: Add setting to require hardware breakpoints. When debugging read-only memory we cannot use software breakpoint. We already have support for hardware breakpoints and users can specify them with `-H`. However, there's no option to force LLDB to use hardware breakpoints internally, for example while stepping. This patch adds a setting target.require-hardware-breakpoint that forces LLDB to always use hardware breakpoints. Because hardware breakpoints are a limited resource and can fail to resolve, this patch also extends error handling in thread plans, where breakpoints are used for stepping. Differential revision: https://reviews.llvm.org/D54221 llvm-svn: 346920 --- lldb/source/Target/ThreadPlanStepRange.cpp | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) (limited to 'lldb/source/Target/ThreadPlanStepRange.cpp') diff --git a/lldb/source/Target/ThreadPlanStepRange.cpp b/lldb/source/Target/ThreadPlanStepRange.cpp index 507f0e7f3a3..7ba68ee8498 100644 --- a/lldb/source/Target/ThreadPlanStepRange.cpp +++ b/lldb/source/Target/ThreadPlanStepRange.cpp @@ -57,7 +57,15 @@ void ThreadPlanStepRange::DidPush() { SetNextBranchBreakpoint(); } -bool ThreadPlanStepRange::ValidatePlan(Stream *error) { return true; } +bool ThreadPlanStepRange::ValidatePlan(Stream *error) { + if (m_could_not_resolve_hw_bp) { + if (error) + error->PutCString( + "Could not create hardware breakpoint for thread plan."); + return false; + } + return true; +} Vote ThreadPlanStepRange::ShouldReportStop(Event *event_ptr) { Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP)); @@ -281,6 +289,7 @@ void ThreadPlanStepRange::ClearNextBranchBreakpoint() { m_next_branch_bp_sp->GetID()); GetTarget().RemoveBreakpointByID(m_next_branch_bp_sp->GetID()); m_next_branch_bp_sp.reset(); + m_could_not_resolve_hw_bp = false; } } @@ -331,6 +340,11 @@ bool ThreadPlanStepRange::SetNextBranchBreakpoint() { m_next_branch_bp_sp = GetTarget().CreateBreakpoint(run_to_address, is_internal, false); if (m_next_branch_bp_sp) { + + if (m_next_branch_bp_sp->IsHardware() && + !m_next_branch_bp_sp->HasResolvedLocations()) + m_could_not_resolve_hw_bp = true; + if (log) { lldb::break_id_t bp_site_id = LLDB_INVALID_BREAK_ID; BreakpointLocationSP bp_loc = @@ -347,8 +361,10 @@ bool ThreadPlanStepRange::SetNextBranchBreakpoint() { 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; -- cgit v1.2.3