aboutsummaryrefslogtreecommitdiff
path: root/lldb/source/Commands/CommandObjectThread.cpp
diff options
context:
space:
mode:
authorJonas Devlieghere <jonas@devlieghere.com>2018-11-15 01:18:15 +0000
committerJonas Devlieghere <jonas@devlieghere.com>2018-11-15 01:18:15 +0000
commite103ae92ef2336854587778bd3ae88a87e409a5e (patch)
treea474b4d1db388480dd129f0ab61a690a4f504ca5 /lldb/source/Commands/CommandObjectThread.cpp
parentdf14b94243e9e8ade2747e6adb8a3d9d2cfa71ae (diff)
downloadllvm-e103ae92ef2336854587778bd3ae88a87e409a5e.zip
llvm-e103ae92ef2336854587778bd3ae88a87e409a5e.tar.gz
llvm-e103ae92ef2336854587778bd3ae88a87e409a5e.tar.bz2
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/Commands/CommandObjectThread.cpp')
-rw-r--r--lldb/source/Commands/CommandObjectThread.cpp41
1 files changed, 25 insertions, 16 deletions
diff --git a/lldb/source/Commands/CommandObjectThread.cpp b/lldb/source/Commands/CommandObjectThread.cpp
index 94cba9d..95c5666 100644
--- a/lldb/source/Commands/CommandObjectThread.cpp
+++ b/lldb/source/Commands/CommandObjectThread.cpp
@@ -650,6 +650,7 @@ protected:
bool_stop_other_threads = true;
ThreadPlanSP new_plan_sp;
+ Status new_plan_status;
if (m_step_type == eStepTypeInto) {
StackFrame *frame = thread->GetStackFrameAtIndex(0).get();
@@ -699,7 +700,7 @@ protected:
abort_other_plans, range,
frame->GetSymbolContext(eSymbolContextEverything),
m_options.m_step_in_target.c_str(), stop_other_threads,
- m_options.m_step_in_avoid_no_debug,
+ new_plan_status, m_options.m_step_in_avoid_no_debug,
m_options.m_step_out_avoid_no_debug);
if (new_plan_sp && !m_options.m_avoid_regexp.empty()) {
@@ -709,7 +710,7 @@ protected:
}
} else
new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction(
- false, abort_other_plans, bool_stop_other_threads);
+ false, abort_other_plans, bool_stop_other_threads, new_plan_status);
} else if (m_step_type == eStepTypeOver) {
StackFrame *frame = thread->GetStackFrameAtIndex(0).get();
@@ -718,25 +719,26 @@ protected:
abort_other_plans,
frame->GetSymbolContext(eSymbolContextEverything).line_entry,
frame->GetSymbolContext(eSymbolContextEverything),
- stop_other_threads, m_options.m_step_out_avoid_no_debug);
+ stop_other_threads, new_plan_status,
+ m_options.m_step_out_avoid_no_debug);
else
new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction(
- true, abort_other_plans, bool_stop_other_threads);
+ true, abort_other_plans, bool_stop_other_threads, new_plan_status);
} else if (m_step_type == eStepTypeTrace) {
new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction(
- false, abort_other_plans, bool_stop_other_threads);
+ false, abort_other_plans, bool_stop_other_threads, new_plan_status);
} else if (m_step_type == eStepTypeTraceOver) {
new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction(
- true, abort_other_plans, bool_stop_other_threads);
+ true, abort_other_plans, bool_stop_other_threads, new_plan_status);
} else if (m_step_type == eStepTypeOut) {
new_plan_sp = thread->QueueThreadPlanForStepOut(
abort_other_plans, nullptr, false, bool_stop_other_threads, eVoteYes,
- eVoteNoOpinion, thread->GetSelectedFrameIndex(),
+ eVoteNoOpinion, thread->GetSelectedFrameIndex(), new_plan_status,
m_options.m_step_out_avoid_no_debug);
} else if (m_step_type == eStepTypeScripted) {
new_plan_sp = thread->QueueThreadPlanForStepScripted(
abort_other_plans, m_options.m_class_name.c_str(),
- bool_stop_other_threads);
+ bool_stop_other_threads, new_plan_status);
} else {
result.AppendError("step type is not supported");
result.SetStatus(eReturnStatusFailed);
@@ -794,7 +796,7 @@ protected:
result.SetStatus(eReturnStatusSuccessContinuingNoResult);
}
} else {
- result.AppendError("Couldn't find thread plan to implement step type.");
+ result.SetError(new_plan_status);
result.SetStatus(eReturnStatusFailed);
}
return result.Succeeded();
@@ -1190,6 +1192,7 @@ protected:
}
ThreadPlanSP new_plan_sp;
+ Status new_plan_status;
if (frame->HasDebugInformation()) {
// Finally we got here... Translate the given line number to a bunch
@@ -1270,13 +1273,19 @@ protected:
new_plan_sp = thread->QueueThreadPlanForStepUntil(
abort_other_plans, &address_list.front(), address_list.size(),
- m_options.m_stop_others, m_options.m_frame_idx);
- // User level plans should be master plans so they can be interrupted
- // (e.g. by hitting a breakpoint) and other plans executed by the user
- // (stepping around the breakpoint) and then a "continue" will resume
- // the original plan.
- new_plan_sp->SetIsMasterPlan(true);
- new_plan_sp->SetOkayToDiscard(false);
+ m_options.m_stop_others, m_options.m_frame_idx, new_plan_status);
+ if (new_plan_sp) {
+ // User level plans should be master plans so they can be interrupted
+ // (e.g. by hitting a breakpoint) and other plans executed by the
+ // user (stepping around the breakpoint) and then a "continue" will
+ // resume the original plan.
+ new_plan_sp->SetIsMasterPlan(true);
+ new_plan_sp->SetOkayToDiscard(false);
+ } else {
+ result.SetError(new_plan_status);
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
} else {
result.AppendErrorWithFormat(
"Frame index %u of thread %u has no debug information.\n",