aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lldb/include/lldb/DataFormatters/DumpValueObjectOptions.h3
-rw-r--r--lldb/include/lldb/DataFormatters/ValueObjectPrinter.h2
-rw-r--r--lldb/include/lldb/Interpreter/CommandInterpreter.h51
-rw-r--r--lldb/include/lldb/Interpreter/OptionGroupValueObjectDisplay.h3
-rw-r--r--lldb/include/lldb/Interpreter/OptionValueProperties.h4
-rw-r--r--lldb/include/lldb/Target/Target.h9
-rw-r--r--lldb/source/Commands/CommandObjectFrame.cpp7
-rw-r--r--lldb/source/Commands/CommandObjectTarget.cpp7
-rw-r--r--lldb/source/DataFormatters/DumpValueObjectOptions.cpp3
-rw-r--r--lldb/source/DataFormatters/ValueObjectPrinter.cpp17
-rw-r--r--lldb/source/Interpreter/CommandInterpreter.cpp3
-rw-r--r--lldb/source/Interpreter/OptionGroupValueObjectDisplay.cpp12
-rw-r--r--lldb/source/Interpreter/OptionValueProperties.cpp11
-rw-r--r--lldb/source/Target/Target.cpp9
-rw-r--r--lldb/source/Target/TargetProperties.td3
15 files changed, 107 insertions, 37 deletions
diff --git a/lldb/include/lldb/DataFormatters/DumpValueObjectOptions.h b/lldb/include/lldb/DataFormatters/DumpValueObjectOptions.h
index cef43f4..c6306c7 100644
--- a/lldb/include/lldb/DataFormatters/DumpValueObjectOptions.h
+++ b/lldb/include/lldb/DataFormatters/DumpValueObjectOptions.h
@@ -66,7 +66,7 @@ public:
DumpValueObjectOptions &
SetMaximumPointerDepth(PointerDepth depth = {PointerDepth::Mode::Never, 0});
- DumpValueObjectOptions &SetMaximumDepth(uint32_t depth = 0);
+ DumpValueObjectOptions &SetMaximumDepth(uint32_t depth, bool is_default);
DumpValueObjectOptions &SetDeclPrintingHelper(DeclPrintingHelper helper);
@@ -125,6 +125,7 @@ public:
SetPointerAsArray(const PointerAsArraySettings &ptr_array);
uint32_t m_max_depth = UINT32_MAX;
+ bool m_max_depth_is_default = true;
lldb::DynamicValueType m_use_dynamic = lldb::eNoDynamicValues;
uint32_t m_omit_summary_depth = 0;
lldb::Format m_format = lldb::eFormatDefault;
diff --git a/lldb/include/lldb/DataFormatters/ValueObjectPrinter.h b/lldb/include/lldb/DataFormatters/ValueObjectPrinter.h
index 833cd5e..90e5402 100644
--- a/lldb/include/lldb/DataFormatters/ValueObjectPrinter.h
+++ b/lldb/include/lldb/DataFormatters/ValueObjectPrinter.h
@@ -117,6 +117,8 @@ protected:
bool PrintChildrenOneLiner(bool hide_names);
+ bool HasReachedMaximumDepth();
+
private:
ValueObject *m_orig_valobj;
ValueObject *m_valobj;
diff --git a/lldb/include/lldb/Interpreter/CommandInterpreter.h b/lldb/include/lldb/Interpreter/CommandInterpreter.h
index f1f715c..55971136 100644
--- a/lldb/include/lldb/Interpreter/CommandInterpreter.h
+++ b/lldb/include/lldb/Interpreter/CommandInterpreter.h
@@ -223,11 +223,11 @@ public:
eBroadcastBitAsynchronousErrorData = (1 << 4)
};
- enum ChildrenTruncatedWarningStatus // tristate boolean to manage children
- // truncation warning
- { eNoTruncation = 0, // never truncated
- eUnwarnedTruncation = 1, // truncated but did not notify
- eWarnedTruncation = 2 // truncated and notified
+ /// Tristate boolean to manage children omission warnings.
+ enum ChildrenOmissionWarningStatus {
+ eNoOmission = 0, ///< No children were omitted.
+ eUnwarnedOmission = 1, ///< Children omitted, and not yet notified.
+ eWarnedOmission = 2 ///< Children omitted and notified.
};
enum CommandTypes {
@@ -496,21 +496,33 @@ public:
}
void ChildrenTruncated() {
- if (m_truncation_warning == eNoTruncation)
- m_truncation_warning = eUnwarnedTruncation;
+ if (m_truncation_warning == eNoOmission)
+ m_truncation_warning = eUnwarnedOmission;
}
- bool TruncationWarningNecessary() {
- return (m_truncation_warning == eUnwarnedTruncation);
+ void SetReachedMaximumDepth() {
+ if (m_max_depth_warning == eNoOmission)
+ m_max_depth_warning = eUnwarnedOmission;
}
- void TruncationWarningGiven() { m_truncation_warning = eWarnedTruncation; }
+ void PrintWarningsIfNecessary(Stream &s, const std::string &cmd_name) {
+ if (m_truncation_warning == eUnwarnedOmission) {
+ s.Printf("*** Some of the displayed variables have more members than the "
+ "debugger will show by default. To show all of them, you can "
+ "either use the --show-all-children option to %s or raise the "
+ "limit by changing the target.max-children-count setting.\n",
+ cmd_name.c_str());
+ m_truncation_warning = eWarnedOmission;
+ }
- const char *TruncationWarningText() {
- return "*** Some of your variables have more members than the debugger "
- "will show by default. To show all of them, you can either use the "
- "--show-all-children option to %s or raise the limit by changing "
- "the target.max-children-count setting.\n";
+ if (m_max_depth_warning == eUnwarnedOmission) {
+ s.Printf("*** Some of the displayed variables have a greater depth of "
+ "members than the debugger will show by default. To increase "
+ "the limit, use the --depth option to %s, or raise the limit by "
+ "changing the target.max-children-depth setting.\n",
+ cmd_name.c_str());
+ m_max_depth_warning = eWarnedOmission;
+ }
}
CommandHistory &GetCommandHistory() { return m_command_history; }
@@ -701,9 +713,12 @@ private:
lldb::IOHandlerSP m_command_io_handler_sp;
char m_comment_char;
bool m_batch_command_mode;
- ChildrenTruncatedWarningStatus m_truncation_warning; // Whether we truncated
- // children and whether
- // the user has been told
+ /// Whether we truncated a value's list of children and whether the user has
+ /// been told.
+ ChildrenOmissionWarningStatus m_truncation_warning;
+ /// Whether we reached the maximum child nesting depth and whether the user
+ /// has been told.
+ ChildrenOmissionWarningStatus m_max_depth_warning;
// FIXME: Stop using this to control adding to the history and then replace
// this with m_command_source_dirs.size().
diff --git a/lldb/include/lldb/Interpreter/OptionGroupValueObjectDisplay.h b/lldb/include/lldb/Interpreter/OptionGroupValueObjectDisplay.h
index 56452f4..9b545c4 100644
--- a/lldb/include/lldb/Interpreter/OptionGroupValueObjectDisplay.h
+++ b/lldb/include/lldb/Interpreter/OptionGroupValueObjectDisplay.h
@@ -43,7 +43,8 @@ public:
lldb::TypeSummaryImplSP summary_sp = lldb::TypeSummaryImplSP());
bool show_types : 1, show_location : 1, flat_output : 1, use_objc : 1,
- use_synth : 1, be_raw : 1, ignore_cap : 1, run_validator : 1;
+ use_synth : 1, be_raw : 1, ignore_cap : 1, run_validator : 1,
+ max_depth_is_default : 1;
uint32_t no_summary_depth;
uint32_t max_depth;
diff --git a/lldb/include/lldb/Interpreter/OptionValueProperties.h b/lldb/include/lldb/Interpreter/OptionValueProperties.h
index 3e5685b..14f496b 100644
--- a/lldb/include/lldb/Interpreter/OptionValueProperties.h
+++ b/lldb/include/lldb/Interpreter/OptionValueProperties.h
@@ -152,6 +152,10 @@ public:
GetPropertyAtIndexAsOptionValueSInt64(const ExecutionContext *exe_ctx,
uint32_t idx) const;
+ OptionValueUInt64 *
+ GetPropertyAtIndexAsOptionValueUInt64(const ExecutionContext *exe_ctx,
+ uint32_t idx) const;
+
int64_t GetPropertyAtIndexAsSInt64(const ExecutionContext *exe_ctx,
uint32_t idx, int64_t fail_value) const;
diff --git a/lldb/include/lldb/Target/Target.h b/lldb/include/lldb/Target/Target.h
index 59617ed..d6193ea 100644
--- a/lldb/include/lldb/Target/Target.h
+++ b/lldb/include/lldb/Target/Target.h
@@ -166,6 +166,15 @@ public:
uint32_t GetMaximumNumberOfChildrenToDisplay() const;
+ /// Get the max depth value, augmented with a bool to indicate whether the
+ /// depth is the default.
+ ///
+ /// When the user has customized the max depth, the bool will be false.
+ ///
+ /// \returns the max depth, and true if the max depth is the system default,
+ /// otherwise false.
+ std::pair<uint32_t, bool> GetMaximumDepthOfChildrenToDisplay() const;
+
uint32_t GetMaximumSizeOfStringSummary() const;
uint32_t GetMaximumMemReadSize() const;
diff --git a/lldb/source/Commands/CommandObjectFrame.cpp b/lldb/source/Commands/CommandObjectFrame.cpp
index ead0594..2a1cef7 100644
--- a/lldb/source/Commands/CommandObjectFrame.cpp
+++ b/lldb/source/Commands/CommandObjectFrame.cpp
@@ -695,11 +695,8 @@ protected:
}
}
- if (m_interpreter.TruncationWarningNecessary()) {
- result.GetOutputStream().Printf(m_interpreter.TruncationWarningText(),
- m_cmd_name.c_str());
- m_interpreter.TruncationWarningGiven();
- }
+ m_interpreter.PrintWarningsIfNecessary(result.GetOutputStream(),
+ m_cmd_name);
// Increment statistics.
bool res = result.Succeeded();
diff --git a/lldb/source/Commands/CommandObjectTarget.cpp b/lldb/source/Commands/CommandObjectTarget.cpp
index aeb65da..5a36298 100644
--- a/lldb/source/Commands/CommandObjectTarget.cpp
+++ b/lldb/source/Commands/CommandObjectTarget.cpp
@@ -972,11 +972,8 @@ protected:
}
}
- if (m_interpreter.TruncationWarningNecessary()) {
- result.GetOutputStream().Printf(m_interpreter.TruncationWarningText(),
- m_cmd_name.c_str());
- m_interpreter.TruncationWarningGiven();
- }
+ m_interpreter.PrintWarningsIfNecessary(result.GetOutputStream(),
+ m_cmd_name);
return result.Succeeded();
}
diff --git a/lldb/source/DataFormatters/DumpValueObjectOptions.cpp b/lldb/source/DataFormatters/DumpValueObjectOptions.cpp
index 46a2a48..38de442 100644
--- a/lldb/source/DataFormatters/DumpValueObjectOptions.cpp
+++ b/lldb/source/DataFormatters/DumpValueObjectOptions.cpp
@@ -38,8 +38,9 @@ DumpValueObjectOptions::SetMaximumPointerDepth(PointerDepth depth) {
}
DumpValueObjectOptions &
-DumpValueObjectOptions::SetMaximumDepth(uint32_t depth) {
+DumpValueObjectOptions::SetMaximumDepth(uint32_t depth, bool is_default) {
m_max_depth = depth;
+ m_max_depth_is_default = is_default;
return *this;
}
diff --git a/lldb/source/DataFormatters/ValueObjectPrinter.cpp b/lldb/source/DataFormatters/ValueObjectPrinter.cpp
index 082ad344..6fd6308 100644
--- a/lldb/source/DataFormatters/ValueObjectPrinter.cpp
+++ b/lldb/source/DataFormatters/ValueObjectPrinter.cpp
@@ -500,7 +500,7 @@ bool ValueObjectPrinter::ShouldPrintChildren(
if (m_options.m_use_objc)
return false;
- if (is_failed_description || m_curr_depth < m_options.m_max_depth) {
+ if (is_failed_description || !HasReachedMaximumDepth()) {
// We will show children for all concrete types. We won't show pointer
// contents unless a pointer depth has been specified. We won't reference
// contents unless the reference is the root object (depth of zero).
@@ -786,9 +786,22 @@ void ValueObjectPrinter::PrintChildrenIfNeeded(bool value_printed,
m_stream->EOL();
} else
PrintChildren(value_printed, summary_printed, curr_ptr_depth);
- } else if (m_curr_depth >= m_options.m_max_depth && IsAggregate() &&
+ } else if (HasReachedMaximumDepth() && IsAggregate() &&
ShouldPrintValueObject()) {
m_stream->PutCString("{...}\n");
+ // The maximum child depth has been reached. If `m_max_depth` is the default
+ // (i.e. the user has _not_ customized it), then lldb presents a warning to
+ // the user. The warning tells the user that the limit has been reached, but
+ // more importantly tells them how to expand the limit if desired.
+ if (m_options.m_max_depth_is_default)
+ m_valobj->GetTargetSP()
+ ->GetDebugger()
+ .GetCommandInterpreter()
+ .SetReachedMaximumDepth();
} else
m_stream->EOL();
}
+
+bool ValueObjectPrinter::HasReachedMaximumDepth() {
+ return m_curr_depth >= m_options.m_max_depth;
+}
diff --git a/lldb/source/Interpreter/CommandInterpreter.cpp b/lldb/source/Interpreter/CommandInterpreter.cpp
index c779795..01a2e3f 100644
--- a/lldb/source/Interpreter/CommandInterpreter.cpp
+++ b/lldb/source/Interpreter/CommandInterpreter.cpp
@@ -128,7 +128,8 @@ CommandInterpreter::CommandInterpreter(Debugger &debugger,
m_debugger(debugger), m_synchronous_execution(true),
m_skip_lldbinit_files(false), m_skip_app_init_files(false),
m_comment_char('#'), m_batch_command_mode(false),
- m_truncation_warning(eNoTruncation), m_command_source_depth(0) {
+ m_truncation_warning(eNoOmission), m_max_depth_warning(eNoOmission),
+ m_command_source_depth(0) {
SetEventName(eBroadcastBitThreadShouldExit, "thread-should-exit");
SetEventName(eBroadcastBitResetPrompt, "reset-prompt");
SetEventName(eBroadcastBitQuitCommandReceived, "quit");
diff --git a/lldb/source/Interpreter/OptionGroupValueObjectDisplay.cpp b/lldb/source/Interpreter/OptionGroupValueObjectDisplay.cpp
index 04861b5..57b5930 100644
--- a/lldb/source/Interpreter/OptionGroupValueObjectDisplay.cpp
+++ b/lldb/source/Interpreter/OptionGroupValueObjectDisplay.cpp
@@ -104,6 +104,8 @@ Status OptionGroupValueObjectDisplay::SetOptionValue(
max_depth = UINT32_MAX;
error.SetErrorStringWithFormat("invalid max depth '%s'",
option_arg.str().c_str());
+ } else {
+ max_depth_is_default = false;
}
break;
@@ -163,6 +165,7 @@ void OptionGroupValueObjectDisplay::OptionParsingStarting(
flat_output = false;
use_objc = false;
max_depth = UINT32_MAX;
+ max_depth_is_default = true;
ptr_depth = 0;
elem_count = 0;
use_synth = true;
@@ -172,9 +175,12 @@ void OptionGroupValueObjectDisplay::OptionParsingStarting(
TargetSP target_sp =
execution_context ? execution_context->GetTargetSP() : TargetSP();
- if (target_sp)
+ if (target_sp) {
use_dynamic = target_sp->GetPreferDynamicValue();
- else {
+ auto max_depth_config = target_sp->GetMaximumDepthOfChildrenToDisplay();
+ max_depth = std::get<uint32_t>(max_depth_config);
+ max_depth_is_default = std::get<bool>(max_depth_config);
+ } else {
// If we don't have any targets, then dynamic values won't do us much good.
use_dynamic = lldb::eNoDynamicValues;
}
@@ -190,7 +196,7 @@ DumpValueObjectOptions OptionGroupValueObjectDisplay::GetAsDumpOptions(
options.SetShowSummary(false);
else
options.SetOmitSummaryDepth(no_summary_depth);
- options.SetMaximumDepth(max_depth)
+ options.SetMaximumDepth(max_depth, max_depth_is_default)
.SetShowTypes(show_types)
.SetShowLocation(show_location)
.SetUseObjectiveC(use_objc)
diff --git a/lldb/source/Interpreter/OptionValueProperties.cpp b/lldb/source/Interpreter/OptionValueProperties.cpp
index 6e65805..b216557 100644
--- a/lldb/source/Interpreter/OptionValueProperties.cpp
+++ b/lldb/source/Interpreter/OptionValueProperties.cpp
@@ -412,6 +412,17 @@ OptionValueSInt64 *OptionValueProperties::GetPropertyAtIndexAsOptionValueSInt64(
return nullptr;
}
+OptionValueUInt64 *OptionValueProperties::GetPropertyAtIndexAsOptionValueUInt64(
+ const ExecutionContext *exe_ctx, uint32_t idx) const {
+ const Property *property = GetPropertyAtIndex(exe_ctx, false, idx);
+ if (property) {
+ OptionValue *value = property->GetValue().get();
+ if (value)
+ return value->GetAsUInt64();
+ }
+ return nullptr;
+}
+
int64_t OptionValueProperties::GetPropertyAtIndexAsSInt64(
const ExecutionContext *exe_ctx, uint32_t idx, int64_t fail_value) const {
const Property *property = GetPropertyAtIndex(exe_ctx, false, idx);
diff --git a/lldb/source/Target/Target.cpp b/lldb/source/Target/Target.cpp
index 8f0a8be5..ed733f2 100644
--- a/lldb/source/Target/Target.cpp
+++ b/lldb/source/Target/Target.cpp
@@ -4236,6 +4236,15 @@ uint32_t TargetProperties::GetMaximumNumberOfChildrenToDisplay() const {
nullptr, idx, g_target_properties[idx].default_uint_value);
}
+std::pair<uint32_t, bool>
+TargetProperties::GetMaximumDepthOfChildrenToDisplay() const {
+ const uint32_t idx = ePropertyMaxChildrenDepth;
+ auto *option_value =
+ m_collection_sp->GetPropertyAtIndexAsOptionValueUInt64(nullptr, idx);
+ bool is_default = !option_value->OptionWasSet();
+ return {option_value->GetCurrentValue(), is_default};
+}
+
uint32_t TargetProperties::GetMaximumSizeOfStringSummary() const {
const uint32_t idx = ePropertyMaxSummaryLength;
return m_collection_sp->GetPropertyAtIndexAsSInt64(
diff --git a/lldb/source/Target/TargetProperties.td b/lldb/source/Target/TargetProperties.td
index 0f46b4c..62d2c86 100644
--- a/lldb/source/Target/TargetProperties.td
+++ b/lldb/source/Target/TargetProperties.td
@@ -72,6 +72,9 @@ let Definition = "target" in {
def MaxChildrenCount: Property<"max-children-count", "SInt64">,
DefaultUnsignedValue<256>,
Desc<"Maximum number of children to expand in any level of depth.">;
+ def MaxChildrenDepth: Property<"max-children-depth", "UInt64">,
+ DefaultUnsignedValue<0xFFFFFFFF>,
+ Desc<"Maximum depth to expand children.">;
def MaxSummaryLength: Property<"max-string-summary-length", "SInt64">,
DefaultUnsignedValue<1024>,
Desc<"Maximum number of characters to show when using %s in summary strings.">;