diff options
author | Jonas Devlieghere <jonas@devlieghere.com> | 2018-11-15 01:18:15 +0000 |
---|---|---|
committer | Jonas Devlieghere <jonas@devlieghere.com> | 2018-11-15 01:18:15 +0000 |
commit | e103ae92ef2336854587778bd3ae88a87e409a5e (patch) | |
tree | a474b4d1db388480dd129f0ab61a690a4f504ca5 /lldb/source/API/SBThread.cpp | |
parent | df14b94243e9e8ade2747e6adb8a3d9d2cfa71ae (diff) | |
download | bcm5719-llvm-e103ae92ef2336854587778bd3ae88a87e409a5e.tar.gz bcm5719-llvm-e103ae92ef2336854587778bd3ae88a87e409a5e.zip |
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
Diffstat (limited to 'lldb/source/API/SBThread.cpp')
-rw-r--r-- | lldb/source/API/SBThread.cpp | 98 |
1 files changed, 58 insertions, 40 deletions
diff --git a/lldb/source/API/SBThread.cpp b/lldb/source/API/SBThread.cpp index b7af4593add..a38b9f6a310 100644 --- a/lldb/source/API/SBThread.cpp +++ b/lldb/source/API/SBThread.cpp @@ -657,6 +657,7 @@ void SBThread::StepOver(lldb::RunMode stop_other_threads, SBError &error) { bool abort_other_plans = false; StackFrameSP frame_sp(thread->GetStackFrameAtIndex(0)); + Status new_plan_status; ThreadPlanSP new_plan_sp; if (frame_sp) { if (frame_sp->HasDebugInformation()) { @@ -664,10 +665,10 @@ void SBThread::StepOver(lldb::RunMode stop_other_threads, SBError &error) { SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything)); new_plan_sp = thread->QueueThreadPlanForStepOverRange( abort_other_plans, sc.line_entry, sc, stop_other_threads, - avoid_no_debug); + new_plan_status, avoid_no_debug); } else { new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction( - true, abort_other_plans, stop_other_threads); + true, abort_other_plans, stop_other_threads, new_plan_status); } } error = ResumeNewPlan(exe_ctx, new_plan_sp.get()); @@ -707,6 +708,7 @@ void SBThread::StepInto(const char *target_name, uint32_t end_line, Thread *thread = exe_ctx.GetThreadPtr(); StackFrameSP frame_sp(thread->GetStackFrameAtIndex(0)); ThreadPlanSP new_plan_sp; + Status new_plan_status; if (frame_sp && frame_sp->HasDebugInformation()) { SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything)); @@ -724,13 +726,17 @@ void SBThread::StepInto(const char *target_name, uint32_t end_line, eLazyBoolCalculate; new_plan_sp = thread->QueueThreadPlanForStepInRange( abort_other_plans, range, sc, target_name, stop_other_threads, - step_in_avoids_code_without_debug_info, + new_plan_status, step_in_avoids_code_without_debug_info, step_out_avoids_code_without_debug_info); } else { new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction( - false, abort_other_plans, stop_other_threads); + false, abort_other_plans, stop_other_threads, new_plan_status); } - error = ResumeNewPlan(exe_ctx, new_plan_sp.get()); + + if (new_plan_status.Success()) + error = ResumeNewPlan(exe_ctx, new_plan_sp.get()); + else + error.SetErrorString(new_plan_status.AsCString()); } void SBThread::StepOut() { @@ -759,11 +765,15 @@ void SBThread::StepOut(SBError &error) { Thread *thread = exe_ctx.GetThreadPtr(); const LazyBool avoid_no_debug = eLazyBoolCalculate; + Status new_plan_status; ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepOut( abort_other_plans, NULL, false, stop_other_threads, eVoteYes, - eVoteNoOpinion, 0, avoid_no_debug)); + eVoteNoOpinion, 0, new_plan_status, avoid_no_debug)); - error = ResumeNewPlan(exe_ctx, new_plan_sp.get()); + if (new_plan_status.Success()) + error = ResumeNewPlan(exe_ctx, new_plan_sp.get()); + else + error.SetErrorString(new_plan_status.AsCString()); } void SBThread::StepOutOfFrame(SBFrame &sb_frame) { @@ -812,11 +822,15 @@ void SBThread::StepOutOfFrame(SBFrame &sb_frame, SBError &error) { return; } + Status new_plan_status; ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepOut( abort_other_plans, NULL, false, stop_other_threads, eVoteYes, - eVoteNoOpinion, frame_sp->GetFrameIndex())); + eVoteNoOpinion, frame_sp->GetFrameIndex(), new_plan_status)); - error = ResumeNewPlan(exe_ctx, new_plan_sp.get()); + if (new_plan_status.Success()) + error = ResumeNewPlan(exe_ctx, new_plan_sp.get()); + else + error.SetErrorString(new_plan_status.AsCString()); } void SBThread::StepInstruction(bool step_over) { @@ -840,10 +854,14 @@ void SBThread::StepInstruction(bool step_over, SBError &error) { } Thread *thread = exe_ctx.GetThreadPtr(); - ThreadPlanSP new_plan_sp( - thread->QueueThreadPlanForStepSingleInstruction(step_over, true, true)); + Status new_plan_status; + ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepSingleInstruction( + step_over, true, true, new_plan_status)); - error = ResumeNewPlan(exe_ctx, new_plan_sp.get()); + if (new_plan_status.Success()) + error = ResumeNewPlan(exe_ctx, new_plan_sp.get()); + else + error.SetErrorString(new_plan_status.AsCString()); } void SBThread::RunToAddress(lldb::addr_t addr) { @@ -873,10 +891,14 @@ void SBThread::RunToAddress(lldb::addr_t addr, SBError &error) { Thread *thread = exe_ctx.GetThreadPtr(); + Status new_plan_status; ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForRunToAddress( - abort_other_plans, target_addr, stop_other_threads)); + abort_other_plans, target_addr, stop_other_threads, new_plan_status)); - error = ResumeNewPlan(exe_ctx, new_plan_sp.get()); + if (new_plan_status.Success()) + error = ResumeNewPlan(exe_ctx, new_plan_sp.get()); + else + error.SetErrorString(new_plan_status.AsCString()); } SBError SBThread::StepOverUntil(lldb::SBFrame &sb_frame, @@ -988,12 +1010,16 @@ SBError SBThread::StepOverUntil(lldb::SBFrame &sb_frame, } else sb_error.SetErrorString("step until target not in current function"); } else { + Status new_plan_status; 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(), new_plan_status)); - sb_error = ResumeNewPlan(exe_ctx, new_plan_sp.get()); + if (new_plan_status.Success()) + sb_error = ResumeNewPlan(exe_ctx, new_plan_sp.get()); + else + sb_error.SetErrorString(new_plan_status.AsCString()); } } else { sb_error.SetErrorString("this SBThread object is invalid"); @@ -1008,7 +1034,7 @@ SBError SBThread::StepUsingScriptedThreadPlan(const char *script_class_name) { SBError SBThread::StepUsingScriptedThreadPlan(const char *script_class_name, bool resume_immediately) { Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); - SBError sb_error; + SBError error; std::unique_lock<std::recursive_mutex> lock; ExecutionContext exe_ctx(m_opaque_sp.get(), lock); @@ -1019,37 +1045,29 @@ SBError SBThread::StepUsingScriptedThreadPlan(const char *script_class_name, } if (!exe_ctx.HasThreadScope()) { - sb_error.SetErrorString("this SBThread object is invalid"); - return sb_error; + error.SetErrorString("this SBThread object is invalid"); + return error; } Thread *thread = exe_ctx.GetThreadPtr(); - ThreadPlanSP thread_plan_sp = - thread->QueueThreadPlanForStepScripted(false, script_class_name, false); + Status new_plan_status; + ThreadPlanSP new_plan_sp = thread->QueueThreadPlanForStepScripted( + false, script_class_name, false, new_plan_status); - if (!thread_plan_sp) { - sb_error.SetErrorStringWithFormat( - "Error queueing thread plan for class: %s", script_class_name); - return sb_error; + if (new_plan_status.Fail()) { + error.SetErrorString(new_plan_status.AsCString()); + return error; } - if (!resume_immediately) { - return sb_error; - } + if (!resume_immediately) + return error; - if (thread_plan_sp) - sb_error = ResumeNewPlan(exe_ctx, thread_plan_sp.get()); - else { - sb_error.SetErrorStringWithFormat( - "Error resuming thread plan for class: %s.", script_class_name); - if (log) - log->Printf("SBThread(%p)::StepUsingScriptedThreadPlan: Error queuing " - "thread plan for class: %s", - static_cast<void *>(exe_ctx.GetThreadPtr()), - script_class_name); - } + if (new_plan_status.Success()) + error = ResumeNewPlan(exe_ctx, new_plan_sp.get()); + else + error.SetErrorString(new_plan_status.AsCString()); - return sb_error; + return error; } SBError SBThread::JumpToLine(lldb::SBFileSpec &file_spec, uint32_t line) { |