[Lldb-commits] [lldb] [lldb] Dump build configuration with `version -v` (PR #170772)
Jonas Devlieghere via lldb-commits
lldb-commits at lists.llvm.org
Thu Dec 4 15:38:31 PST 2025
https://github.com/JDevlieghere updated https://github.com/llvm/llvm-project/pull/170772
>From 38d27e4313ba38b5a54ffaab2ee68f53b21a3f2e Mon Sep 17 00:00:00 2001
From: Jonas Devlieghere <jonas at devlieghere.com>
Date: Thu, 4 Dec 2025 12:00:11 -0800
Subject: [PATCH 1/3] Move GetBuildConfiguration from SBDebugger -> Debugger
---
lldb/include/lldb/Core/Debugger.h | 3 ++
lldb/source/API/SBDebugger.cpp | 52 +----------------------------
lldb/source/Core/Debugger.cpp | 55 +++++++++++++++++++++++++++++++
3 files changed, 59 insertions(+), 51 deletions(-)
diff --git a/lldb/include/lldb/Core/Debugger.h b/lldb/include/lldb/Core/Debugger.h
index ead2ed35fadd4..a39413c06340c 100644
--- a/lldb/include/lldb/Core/Debugger.h
+++ b/lldb/include/lldb/Core/Debugger.h
@@ -107,6 +107,9 @@ class Debugger : public std::enable_shared_from_this<Debugger>,
static void Destroy(lldb::DebuggerSP &debugger_sp);
+ /// Get the build configuration as structured data.
+ static StructuredData::DictionarySP GetBuildConfiguration();
+
static lldb::DebuggerSP FindDebuggerWithID(lldb::user_id_t id);
static lldb::DebuggerSP
diff --git a/lldb/source/API/SBDebugger.cpp b/lldb/source/API/SBDebugger.cpp
index f939955ba57c8..3f34e7acb0673 100644
--- a/lldb/source/API/SBDebugger.cpp
+++ b/lldb/source/API/SBDebugger.cpp
@@ -709,61 +709,11 @@ const char *SBDebugger::StateAsCString(StateType state) {
return lldb_private::StateAsCString(state);
}
-static void AddBoolConfigEntry(StructuredData::Dictionary &dict,
- llvm::StringRef name, bool value,
- llvm::StringRef description) {
- auto entry_up = std::make_unique<StructuredData::Dictionary>();
- entry_up->AddBooleanItem("value", value);
- entry_up->AddStringItem("description", description);
- dict.AddItem(name, std::move(entry_up));
-}
-
-static void AddLLVMTargets(StructuredData::Dictionary &dict) {
- auto array_up = std::make_unique<StructuredData::Array>();
-#define LLVM_TARGET(target) \
- array_up->AddItem(std::make_unique<StructuredData::String>(#target));
-#include "llvm/Config/Targets.def"
- auto entry_up = std::make_unique<StructuredData::Dictionary>();
- entry_up->AddItem("value", std::move(array_up));
- entry_up->AddStringItem("description", "A list of configured LLVM targets.");
- dict.AddItem("targets", std::move(entry_up));
-}
-
SBStructuredData SBDebugger::GetBuildConfiguration() {
LLDB_INSTRUMENT();
- auto config_up = std::make_unique<StructuredData::Dictionary>();
- AddBoolConfigEntry(
- *config_up, "xml", XMLDocument::XMLEnabled(),
- "A boolean value that indicates if XML support is enabled in LLDB");
- AddBoolConfigEntry(
- *config_up, "curl", LLVM_ENABLE_CURL,
- "A boolean value that indicates if CURL support is enabled in LLDB");
- AddBoolConfigEntry(
- *config_up, "curses", LLDB_ENABLE_CURSES,
- "A boolean value that indicates if curses support is enabled in LLDB");
- AddBoolConfigEntry(
- *config_up, "editline", LLDB_ENABLE_LIBEDIT,
- "A boolean value that indicates if editline support is enabled in LLDB");
- AddBoolConfigEntry(*config_up, "editline_wchar", LLDB_EDITLINE_USE_WCHAR,
- "A boolean value that indicates if editline wide "
- "characters support is enabled in LLDB");
- AddBoolConfigEntry(
- *config_up, "lzma", LLDB_ENABLE_LZMA,
- "A boolean value that indicates if lzma support is enabled in LLDB");
- AddBoolConfigEntry(
- *config_up, "python", LLDB_ENABLE_PYTHON,
- "A boolean value that indicates if python support is enabled in LLDB");
- AddBoolConfigEntry(
- *config_up, "lua", LLDB_ENABLE_LUA,
- "A boolean value that indicates if lua support is enabled in LLDB");
- AddBoolConfigEntry(*config_up, "fbsdvmcore", LLDB_ENABLE_FBSDVMCORE,
- "A boolean value that indicates if fbsdvmcore support is "
- "enabled in LLDB");
- AddLLVMTargets(*config_up);
-
SBStructuredData data;
- data.m_impl_up->SetObjectSP(std::move(config_up));
+ data.m_impl_up->SetObjectSP(Debugger::GetBuildConfiguration());
return data;
}
diff --git a/lldb/source/Core/Debugger.cpp b/lldb/source/Core/Debugger.cpp
index 02f38e9094ec5..99f4a728e3f17 100644
--- a/lldb/source/Core/Debugger.cpp
+++ b/lldb/source/Core/Debugger.cpp
@@ -21,12 +21,14 @@
#include "lldb/Core/Telemetry.h"
#include "lldb/DataFormatters/DataVisualization.h"
#include "lldb/Expression/REPL.h"
+#include "lldb/Host/Config.h"
#include "lldb/Host/File.h"
#include "lldb/Host/FileSystem.h"
#include "lldb/Host/HostInfo.h"
#include "lldb/Host/StreamFile.h"
#include "lldb/Host/Terminal.h"
#include "lldb/Host/ThreadLauncher.h"
+#include "lldb/Host/XML.h"
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Interpreter/CommandReturnObject.h"
#include "lldb/Interpreter/OptionValue.h"
@@ -2442,3 +2444,56 @@ llvm::ThreadPoolInterface &Debugger::GetThreadPool() {
"Debugger::GetThreadPool called before Debugger::Initialize");
return *g_thread_pool;
}
+
+static void AddBoolConfigEntry(StructuredData::Dictionary &dict,
+ llvm::StringRef name, bool value,
+ llvm::StringRef description) {
+ auto entry_up = std::make_unique<StructuredData::Dictionary>();
+ entry_up->AddBooleanItem("value", value);
+ entry_up->AddStringItem("description", description);
+ dict.AddItem(name, std::move(entry_up));
+}
+
+static void AddLLVMTargets(StructuredData::Dictionary &dict) {
+ auto array_up = std::make_unique<StructuredData::Array>();
+#define LLVM_TARGET(target) \
+ array_up->AddItem(std::make_unique<StructuredData::String>(#target));
+#include "llvm/Config/Targets.def"
+ auto entry_up = std::make_unique<StructuredData::Dictionary>();
+ entry_up->AddItem("value", std::move(array_up));
+ entry_up->AddStringItem("description", "A list of configured LLVM targets.");
+ dict.AddItem("targets", std::move(entry_up));
+}
+
+StructuredData::DictionarySP Debugger::GetBuildConfiguration() {
+ auto config_up = std::make_unique<StructuredData::Dictionary>();
+ AddBoolConfigEntry(
+ *config_up, "xml", XMLDocument::XMLEnabled(),
+ "A boolean value that indicates if XML support is enabled in LLDB");
+ AddBoolConfigEntry(
+ *config_up, "curl", LLVM_ENABLE_CURL,
+ "A boolean value that indicates if CURL support is enabled in LLDB");
+ AddBoolConfigEntry(
+ *config_up, "curses", LLDB_ENABLE_CURSES,
+ "A boolean value that indicates if curses support is enabled in LLDB");
+ AddBoolConfigEntry(
+ *config_up, "editline", LLDB_ENABLE_LIBEDIT,
+ "A boolean value that indicates if editline support is enabled in LLDB");
+ AddBoolConfigEntry(*config_up, "editline_wchar", LLDB_EDITLINE_USE_WCHAR,
+ "A boolean value that indicates if editline wide "
+ "characters support is enabled in LLDB");
+ AddBoolConfigEntry(
+ *config_up, "lzma", LLDB_ENABLE_LZMA,
+ "A boolean value that indicates if lzma support is enabled in LLDB");
+ AddBoolConfigEntry(
+ *config_up, "python", LLDB_ENABLE_PYTHON,
+ "A boolean value that indicates if python support is enabled in LLDB");
+ AddBoolConfigEntry(
+ *config_up, "lua", LLDB_ENABLE_LUA,
+ "A boolean value that indicates if lua support is enabled in LLDB");
+ AddBoolConfigEntry(*config_up, "fbsdvmcore", LLDB_ENABLE_FBSDVMCORE,
+ "A boolean value that indicates if fbsdvmcore support is "
+ "enabled in LLDB");
+ AddLLVMTargets(*config_up);
+ return config_up;
+}
>From 21a2aac5e5456f9181384406f3b3fcad621a7076 Mon Sep 17 00:00:00 2001
From: Jonas Devlieghere <jonas at devlieghere.com>
Date: Thu, 4 Dec 2025 15:27:27 -0800
Subject: [PATCH 2/3] [lldb] Dump build configuration with `version -v`
Add a verbose option to the `help` command and include the "build
configuration" in the command output. This allows users to quickly
identify if their version of LLDB was built with support for
xml/curl/python/lua etc. This data is already available through the SB
API using `SBDebugger::GetBuildConfiguration`, but this is more
discoverable.
Fixes #170727
---
lldb/source/Commands/CommandObjectVersion.cpp | 52 ++++++++++++++++++-
lldb/source/Commands/CommandObjectVersion.h | 40 +++++++++++++-
lldb/source/Commands/Options.td | 5 ++
3 files changed, 94 insertions(+), 3 deletions(-)
diff --git a/lldb/source/Commands/CommandObjectVersion.cpp b/lldb/source/Commands/CommandObjectVersion.cpp
index f13ec18e240c0..e4e37e3b06d9a 100644
--- a/lldb/source/Commands/CommandObjectVersion.cpp
+++ b/lldb/source/Commands/CommandObjectVersion.cpp
@@ -8,13 +8,20 @@
#include "CommandObjectVersion.h"
+#include "lldb/Core/Debugger.h"
#include "lldb/Interpreter/CommandReturnObject.h"
#include "lldb/Version/Version.h"
using namespace lldb;
using namespace lldb_private;
-// CommandObjectVersion
+#define LLDB_OPTIONS_version
+#include "CommandOptions.inc"
+
+llvm::ArrayRef<OptionDefinition>
+CommandObjectVersion::CommandOptions::GetDefinitions() {
+ return llvm::ArrayRef(g_version_options);
+}
CommandObjectVersion::CommandObjectVersion(CommandInterpreter &interpreter)
: CommandObjectParsed(interpreter, "version",
@@ -22,7 +29,50 @@ CommandObjectVersion::CommandObjectVersion(CommandInterpreter &interpreter)
CommandObjectVersion::~CommandObjectVersion() = default;
+// Dump the array values on a single line.
+static void dump(const StructuredData::Array &array, Stream &s) {
+ s << '[';
+
+ bool add_separator = false;
+ array.ForEach([&](StructuredData::Object *object) -> bool {
+ if (add_separator)
+ s << ", ";
+ s << object->GetStringValue();
+ add_separator = true;
+ return true;
+ });
+
+ s << ']';
+}
+
+// The default dump output is too verbose.
+static void dump(const StructuredData::Dictionary &config, Stream &s) {
+ config.ForEach(
+ [&](llvm::StringRef key, StructuredData::Object *object) -> bool {
+ assert(object);
+
+ StructuredData::Dictionary *value_dict = object->GetAsDictionary();
+ assert(value_dict);
+
+ StructuredData::ObjectSP value_sp = value_dict->GetValueForKey("value");
+ assert(value_sp);
+
+ s << " " << key << ": ";
+ if (StructuredData::Boolean *boolean = value_sp->GetAsBoolean())
+ s << (boolean ? "yes" : "no");
+ else if (StructuredData::Array *array = value_sp->GetAsArray())
+ dump(*array, s);
+ s << '\n';
+
+ return true;
+ });
+}
+
void CommandObjectVersion::DoExecute(Args &args, CommandReturnObject &result) {
result.AppendMessageWithFormat("%s\n", lldb_private::GetVersion());
+
+ if (m_options.verbose)
+ dump(*Debugger::GetBuildConfiguration(), result.GetOutputStream());
+
result.SetStatus(eReturnStatusSuccessFinishResult);
}
diff --git a/lldb/source/Commands/CommandObjectVersion.h b/lldb/source/Commands/CommandObjectVersion.h
index 4ba081bf8706d..ea2741c8c79c4 100644
--- a/lldb/source/Commands/CommandObjectVersion.h
+++ b/lldb/source/Commands/CommandObjectVersion.h
@@ -9,20 +9,56 @@
#ifndef LLDB_SOURCE_COMMANDS_COMMANDOBJECTVERSION_H
#define LLDB_SOURCE_COMMANDS_COMMANDOBJECTVERSION_H
+#include "lldb/Host/OptionParser.h"
#include "lldb/Interpreter/CommandObject.h"
+#include "lldb/Interpreter/Options.h"
namespace lldb_private {
-// CommandObjectVersion
-
class CommandObjectVersion : public CommandObjectParsed {
public:
CommandObjectVersion(CommandInterpreter &interpreter);
~CommandObjectVersion() override;
+ class CommandOptions : public Options {
+ public:
+ CommandOptions() = default;
+
+ ~CommandOptions() override = default;
+
+ Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
+ ExecutionContext *execution_context) override {
+ Status error;
+ const int short_option = m_getopt_table[option_idx].val;
+
+ switch (short_option) {
+ case 'v':
+ verbose = true;
+ break;
+ default:
+ llvm_unreachable("Unimplemented option");
+ }
+
+ return error;
+ }
+
+ void OptionParsingStarting(ExecutionContext *execution_context) override {
+ verbose = false;
+ }
+
+ llvm::ArrayRef<OptionDefinition> GetDefinitions() override;
+
+ bool verbose;
+ };
+
+ Options *GetOptions() override { return &m_options; }
+
protected:
void DoExecute(Args &args, CommandReturnObject &result) override;
+
+private:
+ CommandOptions m_options;
};
} // namespace lldb_private
diff --git a/lldb/source/Commands/Options.td b/lldb/source/Commands/Options.td
index ed061312e2bb4..4abdbf3e596fd 100644
--- a/lldb/source/Commands/Options.td
+++ b/lldb/source/Commands/Options.td
@@ -2432,3 +2432,8 @@ let Command = "statistics dump" in {
"enabled state. Defaults to true for both summary and default "
"mode.">;
}
+
+let Command = "version" in {
+ def version_verbose : Option<"verbose", "v">,
+ Desc<"Include build configuration in version output.">;
+}
>From 8b90d98257abbbe30d50f9556cf060c8d9e6ab9c Mon Sep 17 00:00:00 2001
From: Jonas Devlieghere <jonas at devlieghere.com>
Date: Thu, 4 Dec 2025 15:38:18 -0800
Subject: [PATCH 3/3] Add test
---
lldb/test/Shell/Commands/command-version.test | 6 ++++++
1 file changed, 6 insertions(+)
create mode 100644 lldb/test/Shell/Commands/command-version.test
diff --git a/lldb/test/Shell/Commands/command-version.test b/lldb/test/Shell/Commands/command-version.test
new file mode 100644
index 0000000000000..ccd7bc7e8fd76
--- /dev/null
+++ b/lldb/test/Shell/Commands/command-version.test
@@ -0,0 +1,6 @@
+RUN: %lldb -b -o 'version -v' | FileCheck %s
+
+CHECK: lldb version
+CHECK: xml:
+CHECK: python:
+CHECK: targets: [{{.*}}]
More information about the lldb-commits
mailing list