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
diff --git a/lldb/source/API/SBThread.cpp b/lldb/source/API/SBThread.cpp
index b7af459..a38b9f6 100644
--- a/lldb/source/API/SBThread.cpp
+++ b/lldb/source/API/SBThread.cpp
@@ -657,6 +657,7 @@
   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 @@
       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 @@
   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 @@
         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 @@
   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 @@
     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 @@
   }
 
   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 @@
 
   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 @@
       } 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,
                                               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 @@
   }
 
   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) {