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/Target/Target.cpp b/lldb/source/Target/Target.cpp
index c8fea37..fe46c7b 100644
--- a/lldb/source/Target/Target.cpp
+++ b/lldb/source/Target/Target.cpp
@@ -627,7 +627,8 @@
bool resolve_indirect_symbols) {
BreakpointSP bp_sp;
if (filter_sp && resolver_sp) {
- bp_sp.reset(new Breakpoint(*this, filter_sp, resolver_sp, request_hardware,
+ const bool hardware = request_hardware || GetRequireHardwareBreakpoints();
+ bp_sp.reset(new Breakpoint(*this, filter_sp, resolver_sp, hardware,
resolve_indirect_symbols));
resolver_sp->SetBreakpoint(bp_sp.get());
AddBreakpoint(bp_sp, internal);
@@ -3135,6 +3136,7 @@
// class TargetProperties
//--------------------------------------------------------------
+// clang-format off
static constexpr OptionEnumValueElement g_dynamic_value_types[] = {
{eNoDynamicValues, "no-dynamic-values",
"Don't calculate the dynamic type of values"},
@@ -3362,7 +3364,10 @@
nullptr, {}, "If true, LLDB will show variables that are meant to "
"support the operation of a language's runtime support."},
{"non-stop-mode", OptionValue::eTypeBoolean, false, 0, nullptr, {},
- "Disable lock-step debugging, instead control threads independently."}};
+ "Disable lock-step debugging, instead control threads independently."},
+ {"require-hardware-breakpoint", OptionValue::eTypeBoolean, false, 0,
+ nullptr, {}, "Require all breakpoints to be hardware breakpoints."}};
+// clang-format on
enum {
ePropertyDefaultArch,
@@ -3407,7 +3412,8 @@
ePropertyTrapHandlerNames,
ePropertyDisplayRuntimeSupportValues,
ePropertyNonStopModeEnabled,
- ePropertyExperimental
+ ePropertyRequireHardwareBreakpoints,
+ ePropertyExperimental,
};
class TargetOptionValueProperties : public OptionValueProperties {
@@ -4005,6 +4011,17 @@
SetDisableSTDIO(launch_info.GetFlags().Test(lldb::eLaunchFlagDisableSTDIO));
}
+bool TargetProperties::GetRequireHardwareBreakpoints() const {
+ const uint32_t idx = ePropertyRequireHardwareBreakpoints;
+ return m_collection_sp->GetPropertyAtIndexAsBoolean(
+ nullptr, idx, g_properties[idx].default_uint_value != 0);
+}
+
+void TargetProperties::SetRequireHardwareBreakpoints(bool b) {
+ const uint32_t idx = ePropertyRequireHardwareBreakpoints;
+ m_collection_sp->SetPropertyAtIndexAsBoolean(nullptr, idx, b);
+}
+
void TargetProperties::Arg0ValueChangedCallback(void *target_property_ptr,
OptionValue *) {
TargetProperties *this_ =