aboutsummaryrefslogtreecommitdiff
path: root/lldb/tools
diff options
context:
space:
mode:
authorWalter Erquinigo <a20012251@gmail.com>2023-11-13 21:10:16 -0500
committerGitHub <noreply@github.com>2023-11-13 21:10:16 -0500
commitd9ec4b24a84addb8bd77b5d9dd990181351cf84c (patch)
treec10d8afd9e89c5db2977607d7ddc30c11dd56f6e /lldb/tools
parent0e1a52f556a90cc7b7ce7666fc476c99cf7bfb02 (diff)
downloadllvm-d9ec4b24a84addb8bd77b5d9dd990181351cf84c.zip
llvm-d9ec4b24a84addb8bd77b5d9dd990181351cf84c.tar.gz
llvm-d9ec4b24a84addb8bd77b5d9dd990181351cf84c.tar.bz2
[lldb-dap] Add an option to provide a format for stack frames (#71843)
When this option gets enabled, descriptions of stack frames will be generated using the format provided in the launch configuration instead of simply calling `SBFrame::GetDisplayFunctionName`. This allows lldb-dap to show an output similar to the one in the CLI.
Diffstat (limited to 'lldb/tools')
-rw-r--r--lldb/tools/lldb-dap/DAP.cpp15
-rw-r--r--lldb/tools/lldb-dap/DAP.h4
-rw-r--r--lldb/tools/lldb-dap/JSONUtils.cpp17
-rw-r--r--lldb/tools/lldb-dap/lldb-dap.cpp2
-rw-r--r--lldb/tools/lldb-dap/package.json10
5 files changed, 43 insertions, 5 deletions
diff --git a/lldb/tools/lldb-dap/DAP.cpp b/lldb/tools/lldb-dap/DAP.cpp
index 1bff198..ba111a7 100644
--- a/lldb/tools/lldb-dap/DAP.cpp
+++ b/lldb/tools/lldb-dap/DAP.cpp
@@ -824,4 +824,19 @@ bool ReplModeRequestHandler::DoExecute(lldb::SBDebugger debugger,
return true;
}
+void DAP::SetFrameFormat(llvm::StringRef format) {
+ if (format.empty())
+ return;
+ lldb::SBError error;
+ g_dap.frame_format = lldb::SBFormat(format.data(), error);
+ if (error.Fail()) {
+ g_dap.SendOutput(
+ OutputType::Console,
+ llvm::formatv(
+ "The provided frame format '{0}' couldn't be parsed: {1}\n", format,
+ error.GetCString())
+ .str());
+ }
+}
+
} // namespace lldb_dap
diff --git a/lldb/tools/lldb-dap/DAP.h b/lldb/tools/lldb-dap/DAP.h
index b00c103..11c2cc1 100644
--- a/lldb/tools/lldb-dap/DAP.h
+++ b/lldb/tools/lldb-dap/DAP.h
@@ -36,6 +36,7 @@
#include "lldb/API/SBCommunication.h"
#include "lldb/API/SBDebugger.h"
#include "lldb/API/SBEvent.h"
+#include "lldb/API/SBFormat.h"
#include "lldb/API/SBHostOS.h"
#include "lldb/API/SBInstruction.h"
#include "lldb/API/SBInstructionList.h"
@@ -189,6 +190,7 @@ struct DAP {
ReplMode repl_mode;
bool auto_repl_mode_collision_warning;
std::string command_escape_prefix = "`";
+ lldb::SBFormat frame_format;
DAP();
~DAP();
@@ -305,6 +307,8 @@ struct DAP {
/// \return Error if waiting for the process fails, no error if succeeds.
lldb::SBError WaitForProcessToStop(uint32_t seconds);
+ void SetFrameFormat(llvm::StringRef format);
+
private:
// Send the JSON in "json_str" to the "out" stream. Correctly send the
// "Content-Length:" field followed by the length, followed by the raw
diff --git a/lldb/tools/lldb-dap/JSONUtils.cpp b/lldb/tools/lldb-dap/JSONUtils.cpp
index 2ff1761..2023291 100644
--- a/lldb/tools/lldb-dap/JSONUtils.cpp
+++ b/lldb/tools/lldb-dap/JSONUtils.cpp
@@ -785,11 +785,18 @@ llvm::json::Value CreateStackFrame(lldb::SBFrame &frame) {
int64_t frame_id = MakeDAPFrameID(frame);
object.try_emplace("id", frame_id);
- // `function_name` can be a nullptr, which throws an error when assigned to an
- // `std::string`.
- const char *function_name = frame.GetDisplayFunctionName();
- std::string frame_name =
- function_name == nullptr ? std::string() : function_name;
+ std::string frame_name;
+ lldb::SBStream stream;
+ if (g_dap.frame_format &&
+ frame.GetDescriptionWithFormat(g_dap.frame_format, stream).Success()) {
+ frame_name = stream.GetData();
+
+ // `function_name` can be a nullptr, which throws an error when assigned to
+ // an `std::string`.
+ } else if (const char *name = frame.GetDisplayFunctionName()) {
+ frame_name = name;
+ }
+
if (frame_name.empty()) {
// If the function name is unavailable, display the pc address as a 16-digit
// hex string, e.g. "0x0000000000012345"
diff --git a/lldb/tools/lldb-dap/lldb-dap.cpp b/lldb/tools/lldb-dap/lldb-dap.cpp
index e103aab..01738b3 100644
--- a/lldb/tools/lldb-dap/lldb-dap.cpp
+++ b/lldb/tools/lldb-dap/lldb-dap.cpp
@@ -653,6 +653,7 @@ void request_attach(const llvm::json::Object &request) {
GetBoolean(arguments, "enableSyntheticChildDebugging", false);
g_dap.command_escape_prefix =
GetString(arguments, "commandEscapePrefix", "`");
+ g_dap.SetFrameFormat(GetString(arguments, "customFrameFormat"));
// This is a hack for loading DWARF in .o files on Mac where the .o files
// in the debug map of the main executable have relative paths which require
@@ -1805,6 +1806,7 @@ void request_launch(const llvm::json::Object &request) {
GetBoolean(arguments, "enableSyntheticChildDebugging", false);
g_dap.command_escape_prefix =
GetString(arguments, "commandEscapePrefix", "`");
+ g_dap.SetFrameFormat(GetString(arguments, "customFrameFormat"));
// This is a hack for loading DWARF in .o files on Mac where the .o files
// in the debug map of the main executable have relative paths which require
diff --git a/lldb/tools/lldb-dap/package.json b/lldb/tools/lldb-dap/package.json
index a0ae7ac..6d6c46b 100644
--- a/lldb/tools/lldb-dap/package.json
+++ b/lldb/tools/lldb-dap/package.json
@@ -255,6 +255,11 @@
"type": "string",
"description": "The escape prefix to use for executing regular LLDB commands in the Debug Console, instead of printing variables. Defaults to a back-tick (`). If it's an empty string, then all expression in the Debug Console are treated as regular LLDB commands.",
"default": "`"
+ },
+ "customFrameFormat": {
+ "type": "string",
+ "description": "If non-empty, stack frames will have descriptions generated based on the provided format. See https://lldb.llvm.org/use/formatting.html for an explanation on format strings for frames. If the format string contains errors, an error message will be displayed on the Debug Console and the default frame names will be used. This might come with a performance cost because debug information might need to be processed to generate the description.",
+ "default": ""
}
}
},
@@ -349,6 +354,11 @@
"type": "string",
"description": "The escape prefix character to use for executing regular LLDB commands in the Debug Console, instead of printing variables. Defaults to a back-tick (`). If empty, then all expression in the Debug Console are treated as regular LLDB commands.",
"default": "`"
+ },
+ "customFrameFormat": {
+ "type": "string",
+ "description": "If non-empty, stack frames will have descriptions generated based on the provided format. See https://lldb.llvm.org/use/formatting.html for an explanation on format strings for frames. If the format string contains errors, an error message will be displayed on the Debug Console and the default frame names will be used. This might come with a performance cost because debug information might need to be processed to generate the description.",
+ "default": ""
}
}
}