[Lldb-commits] [lldb] [lldb-dap] Use protocol types for exceptioninfo (PR #164318)
Ebuka Ezike via lldb-commits
lldb-commits at lists.llvm.org
Wed Oct 22 04:06:24 PDT 2025
https://github.com/da-viper updated https://github.com/llvm/llvm-project/pull/164318
>From c879be8e419a03b4a3694afaa17e73907d701aee Mon Sep 17 00:00:00 2001
From: Ebuka Ezike <yerimyah1 at gmail.com>
Date: Wed, 15 Oct 2025 16:11:57 +0100
Subject: [PATCH 1/4] [lldb-dap] use protocol types for exceptionInfo
---
.../Handler/ExceptionInfoRequestHandler.cpp | 210 +++++-------------
lldb/tools/lldb-dap/Handler/RequestHandler.h | 10 +-
.../lldb-dap/Protocol/ProtocolRequests.h | 22 ++
.../tools/lldb-dap/Protocol/ProtocolTypes.cpp | 33 +++
lldb/tools/lldb-dap/Protocol/ProtocolTypes.h | 30 +++
5 files changed, 151 insertions(+), 154 deletions(-)
diff --git a/lldb/tools/lldb-dap/Handler/ExceptionInfoRequestHandler.cpp b/lldb/tools/lldb-dap/Handler/ExceptionInfoRequestHandler.cpp
index c1c2adb32a510..a1aa3865617f0 100644
--- a/lldb/tools/lldb-dap/Handler/ExceptionInfoRequestHandler.cpp
+++ b/lldb/tools/lldb-dap/Handler/ExceptionInfoRequestHandler.cpp
@@ -7,168 +7,76 @@
//===----------------------------------------------------------------------===//
#include "DAP.h"
-#include "EventHelper.h"
-#include "JSONUtils.h"
+#include "DAPError.h"
+#include "Protocol/ProtocolRequests.h"
+#include "Protocol/ProtocolTypes.h"
#include "RequestHandler.h"
#include "lldb/API/SBStream.h"
+using namespace lldb_dap::protocol;
+
namespace lldb_dap {
-// "ExceptionInfoRequest": {
-// "allOf": [ { "$ref": "#/definitions/Request" }, {
-// "type": "object",
-// "description": "Retrieves the details of the exception that
-// caused this event to be raised. Clients should only call this request if
-// the corresponding capability `supportsExceptionInfoRequest` is true.",
-// "properties": {
-// "command": {
-// "type": "string",
-// "enum": [ "exceptionInfo" ]
-// },
-// "arguments": {
-// "$ref": "#/definitions/ExceptionInfoArguments"
-// }
-// },
-// "required": [ "command", "arguments" ]
-// }]
-// },
-// "ExceptionInfoArguments": {
-// "type": "object",
-// "description": "Arguments for `exceptionInfo` request.",
-// "properties": {
-// "threadId": {
-// "type": "integer",
-// "description": "Thread for which exception information should be
-// retrieved."
-// }
-// },
-// "required": [ "threadId" ]
-// },
-// "ExceptionInfoResponse": {
-// "allOf": [ { "$ref": "#/definitions/Response" }, {
-// "type": "object",
-// "description": "Response to `exceptionInfo` request.",
-// "properties": {
-// "body": {
-// "type": "object",
-// "properties": {
-// "exceptionId": {
-// "type": "string",
-// "description": "ID of the exception that was thrown."
-// },
-// "description": {
-// "type": "string",
-// "description": "Descriptive text for the exception."
-// },
-// "breakMode": {
-// "$ref": "#/definitions/ExceptionBreakMode",
-// "description": "Mode that caused the exception notification to
-// be raised."
-// },
-// "details": {
-// "$ref": "#/definitions/ExceptionDetails",
-// "description": "Detailed information about the exception."
-// }
-// },
-// "required": [ "exceptionId", "breakMode" ]
-// }
-// },
-// "required": [ "body" ]
-// }]
-// }
-// "ExceptionDetails": {
-// "type": "object",
-// "description": "Detailed information about an exception that has
-// occurred.", "properties": {
-// "message": {
-// "type": "string",
-// "description": "Message contained in the exception."
-// },
-// "typeName": {
-// "type": "string",
-// "description": "Short type name of the exception object."
-// },
-// "fullTypeName": {
-// "type": "string",
-// "description": "Fully-qualified type name of the exception object."
-// },
-// "evaluateName": {
-// "type": "string",
-// "description": "An expression that can be evaluated in the current
-// scope to obtain the exception object."
-// },
-// "stackTrace": {
-// "type": "string",
-// "description": "Stack trace at the time the exception was thrown."
-// },
-// "innerException": {
-// "type": "array",
-// "items": {
-// "$ref": "#/definitions/ExceptionDetails"
-// },
-// "description": "Details of the exception contained by this exception,
-// if any."
-// }
-// }
-// },
-void ExceptionInfoRequestHandler::operator()(
- const llvm::json::Object &request) const {
- llvm::json::Object response;
- FillResponse(request, response);
- const auto *arguments = request.getObject("arguments");
- llvm::json::Object body;
- lldb::SBThread thread = dap.GetLLDBThread(*arguments);
- if (thread.IsValid()) {
- auto stopReason = thread.GetStopReason();
- if (stopReason == lldb::eStopReasonSignal)
- body.try_emplace("exceptionId", "signal");
- else if (stopReason == lldb::eStopReasonBreakpoint) {
- ExceptionBreakpoint *exc_bp = dap.GetExceptionBPFromStopReason(thread);
- if (exc_bp) {
- EmplaceSafeString(body, "exceptionId", exc_bp->GetFilter());
- EmplaceSafeString(body, "description", exc_bp->GetLabel());
- } else {
- body.try_emplace("exceptionId", "exception");
- }
+/// Retrieves the details of the exception that caused this event to be raised.
+///
+/// Clients should only call this request if the corresponding capability
+/// `supportsExceptionInfoRequest` is true.
+llvm::Expected<ExceptionInfoResponseBody>
+ExceptionInfoRequestHandler::Run(const ExceptionInfoArguments &args) const {
+
+ lldb::SBThread thread = dap.GetLLDBThread(args.threadId);
+ if (!thread.IsValid())
+ return llvm::make_error<DAPError>(
+ llvm::formatv("Invalid thread id: {}", args.threadId).str());
+
+ ExceptionInfoResponseBody response;
+ response.breakMode = eExceptionBreakModeAlways;
+ lldb::StopReason stop_reason = thread.GetStopReason();
+ switch (stop_reason) {
+ case lldb::eStopReasonSignal:
+ response.exceptionId = "signal";
+ break;
+ case lldb::eStopReasonBreakpoint: {
+ ExceptionBreakpoint *exc_bp = dap.GetExceptionBPFromStopReason(thread);
+ if (exc_bp) {
+ response.exceptionId = exc_bp->GetFilter();
+ response.description = exc_bp->GetLabel();
} else {
- body.try_emplace("exceptionId", "exception");
+ response.exceptionId = "exception";
}
- if (!ObjectContainsKey(body, "description")) {
- char description[1024];
- if (thread.GetStopDescription(description, sizeof(description))) {
- EmplaceSafeString(body, "description", description);
- }
+ } break;
+ default:
+ response.exceptionId = "exception";
+ }
+
+ if (response.description.empty()) {
+ const size_t buffer_size = thread.GetStopDescription(nullptr, 0);
+ if (buffer_size > 0) {
+ std::string &buffer = response.description;
+ buffer.resize(buffer_size);
+ thread.GetStopDescription(buffer.data(), buffer.size());
}
- body.try_emplace("breakMode", "always");
- auto exception = thread.GetCurrentException();
- if (exception.IsValid()) {
- llvm::json::Object details;
- lldb::SBStream stream;
- if (exception.GetDescription(stream)) {
- EmplaceSafeString(details, "message", stream.GetData());
- }
+ }
- auto exceptionBacktrace = thread.GetCurrentExceptionBacktrace();
- if (exceptionBacktrace.IsValid()) {
- lldb::SBStream stream;
- exceptionBacktrace.GetDescription(stream);
- for (uint32_t i = 0; i < exceptionBacktrace.GetNumFrames(); i++) {
- lldb::SBFrame frame = exceptionBacktrace.GetFrameAtIndex(i);
- frame.GetDescription(stream);
- }
- EmplaceSafeString(details, "stackTrace", stream.GetData());
- }
+ if (lldb::SBValue exception = thread.GetCurrentException()) {
+ lldb::SBStream stream;
+ response.details = ExceptionDetails{};
+ if (exception.GetDescription(stream)) {
+ response.details->message = stream.GetData();
+ }
+
+ if (lldb::SBThread exception_backtrace =
+ thread.GetCurrentExceptionBacktrace()) {
+ stream.Clear();
+ exception_backtrace.GetDescription(stream);
- body.try_emplace("details", std::move(details));
+ for (uint32_t idx = 0; idx < exception_backtrace.GetNumFrames(); idx++) {
+ lldb::SBFrame frame = exception_backtrace.GetFrameAtIndex(idx);
+ frame.GetDescription(stream);
+ }
+ response.details->stackTrace = stream.GetData();
}
- // auto excInfoCount = thread.GetStopReasonDataCount();
- // for (auto i=0; i<excInfoCount; ++i) {
- // uint64_t exc_data = thread.GetStopReasonDataAtIndex(i);
- // }
- } else {
- response["success"] = llvm::json::Value(false);
}
- response.try_emplace("body", std::move(body));
- dap.SendJSON(llvm::json::Value(std::move(response)));
+ return response;
}
} // namespace lldb_dap
diff --git a/lldb/tools/lldb-dap/Handler/RequestHandler.h b/lldb/tools/lldb-dap/Handler/RequestHandler.h
index 977a247996750..7a7e1263c66f4 100644
--- a/lldb/tools/lldb-dap/Handler/RequestHandler.h
+++ b/lldb/tools/lldb-dap/Handler/RequestHandler.h
@@ -302,14 +302,18 @@ class EvaluateRequestHandler : public LegacyRequestHandler {
}
};
-class ExceptionInfoRequestHandler : public LegacyRequestHandler {
+class ExceptionInfoRequestHandler
+ : public RequestHandler<
+ protocol::ExceptionInfoArguments,
+ llvm::Expected<protocol::ExceptionInfoResponseBody>> {
public:
- using LegacyRequestHandler::LegacyRequestHandler;
+ using RequestHandler::RequestHandler;
static llvm::StringLiteral GetCommand() { return "exceptionInfo"; }
FeatureSet GetSupportedFeatures() const override {
return {protocol::eAdapterFeatureExceptionInfoRequest};
}
- void operator()(const llvm::json::Object &request) const override;
+ llvm::Expected<protocol::ExceptionInfoResponseBody>
+ Run(const protocol::ExceptionInfoArguments &args) const override;
};
class InitializeRequestHandler
diff --git a/lldb/tools/lldb-dap/Protocol/ProtocolRequests.h b/lldb/tools/lldb-dap/Protocol/ProtocolRequests.h
index a85a68b87014c..53e551ac2ec64 100644
--- a/lldb/tools/lldb-dap/Protocol/ProtocolRequests.h
+++ b/lldb/tools/lldb-dap/Protocol/ProtocolRequests.h
@@ -1039,6 +1039,28 @@ struct ModuleSymbolsResponseBody {
};
llvm::json::Value toJSON(const ModuleSymbolsResponseBody &);
+struct ExceptionInfoArguments {
+ /// Thread for which exception information should be retrieved.
+ lldb::tid_t threadId = LLDB_INVALID_THREAD_ID;
+};
+bool fromJSON(const llvm::json::Value &, ExceptionInfoArguments &,
+ llvm::json::Path);
+
+struct ExceptionInfoResponseBody {
+ /// ID of the exception that was thrown.
+ std::string exceptionId;
+
+ /// Descriptive text for the exception.
+ std::string description;
+
+ /// Mode that caused the exception notification to be raised.
+ ExceptionBreakMode breakMode;
+
+ /// Detailed information about the exception.
+ std::optional<ExceptionDetails> details;
+};
+llvm::json::Value toJSON(const ExceptionInfoResponseBody &);
+
} // namespace lldb_dap::protocol
#endif
diff --git a/lldb/tools/lldb-dap/Protocol/ProtocolTypes.cpp b/lldb/tools/lldb-dap/Protocol/ProtocolTypes.cpp
index dc8edaadcd9bb..95007013742a0 100644
--- a/lldb/tools/lldb-dap/Protocol/ProtocolTypes.cpp
+++ b/lldb/tools/lldb-dap/Protocol/ProtocolTypes.cpp
@@ -1136,4 +1136,37 @@ bool fromJSON(const json::Value &Param, Variable &V, json::Path Path) {
Path, /*required=*/false);
}
+json::Value toJSON(const ExceptionBreakMode Mode) {
+ switch (Mode) {
+ case eExceptionBreakModeNever:
+ return "never";
+ case eExceptionBreakModeAlways:
+ return "always";
+ case eExceptionBreakModeUnhandled:
+ return "unhandled";
+ case eExceptionBreakModeUserUnhandled:
+ return "userUnhandled";
+ }
+ llvm_unreachable("unhandled exception breakMode.");
+}
+
+json::Value toJSON(const ExceptionDetails &ED) {
+ json::Object result;
+
+ if (!ED.message.empty())
+ result.insert({"message", ED.message});
+ if (!ED.typeName.empty())
+ result.insert({"typeName", ED.typeName});
+ if (!ED.fullTypeName.empty())
+ result.insert({"fullTypeName", ED.fullTypeName});
+ if (!ED.evaluateName.empty())
+ result.insert({"evaluateName", ED.evaluateName});
+ if (!ED.stackTrace.empty())
+ result.insert({"stackTrace", ED.stackTrace});
+ if (!ED.innerException.empty())
+ result.insert({"innerException", ED.innerException});
+
+ return result;
+}
+
} // namespace lldb_dap::protocol
diff --git a/lldb/tools/lldb-dap/Protocol/ProtocolTypes.h b/lldb/tools/lldb-dap/Protocol/ProtocolTypes.h
index 7077df90a85b5..6d85c74377bd3 100644
--- a/lldb/tools/lldb-dap/Protocol/ProtocolTypes.h
+++ b/lldb/tools/lldb-dap/Protocol/ProtocolTypes.h
@@ -1007,6 +1007,36 @@ struct Variable {
llvm::json::Value toJSON(const Variable &);
bool fromJSON(const llvm::json::Value &, Variable &, llvm::json::Path);
+enum ExceptionBreakMode : unsigned {
+ eExceptionBreakModeNever,
+ eExceptionBreakModeAlways,
+ eExceptionBreakModeUnhandled,
+ eExceptionBreakModeUserUnhandled,
+};
+llvm::json::Value toJSON(ExceptionBreakMode);
+
+struct ExceptionDetails {
+ /// Message contained in the exception.
+ std::string message;
+
+ /// Short type name of the exception object.
+ std::string typeName;
+
+ /// Fully-qualified type name of the exception object.
+ std::string fullTypeName;
+
+ /// An expression that can be evaluated in the current scope to obtain the
+ /// exception object.
+ std::string evaluateName;
+
+ /// Stack trace at the time the exception was thrown.
+ std::string stackTrace;
+
+ /// Details of the exception contained by this exception, if any.
+ std::vector<ExceptionDetails> innerException;
+};
+llvm::json::Value toJSON(const ExceptionDetails &);
+
} // namespace lldb_dap::protocol
#endif
>From 32e9a56140c8e07ebaa7cb6aba17facad103161d Mon Sep 17 00:00:00 2001
From: Ebuka Ezike <yerimyah1 at gmail.com>
Date: Wed, 15 Oct 2025 16:12:47 +0100
Subject: [PATCH 2/4] [lldb-dap] Add the new test type.
---
.../lldb-dap/Protocol/ProtocolRequests.cpp | 18 +++++
lldb/unittests/DAP/CMakeLists.txt | 1 +
lldb/unittests/DAP/ProtocolRequestsTest.cpp | 69 +++++++++++++++++++
lldb/unittests/DAP/ProtocolTypesTest.cpp | 48 +++++++++++++
.../TestingSupport/TestUtilities.cpp | 5 ++
lldb/unittests/TestingSupport/TestUtilities.h | 4 ++
6 files changed, 145 insertions(+)
create mode 100644 lldb/unittests/DAP/ProtocolRequestsTest.cpp
diff --git a/lldb/tools/lldb-dap/Protocol/ProtocolRequests.cpp b/lldb/tools/lldb-dap/Protocol/ProtocolRequests.cpp
index b9393356b4e01..e207aad2167d6 100644
--- a/lldb/tools/lldb-dap/Protocol/ProtocolRequests.cpp
+++ b/lldb/tools/lldb-dap/Protocol/ProtocolRequests.cpp
@@ -625,4 +625,22 @@ llvm::json::Value toJSON(const ModuleSymbolsResponseBody &DGMSR) {
return result;
}
+bool fromJSON(const json::Value &Params, ExceptionInfoArguments &Args,
+ json::Path Path) {
+ json::ObjectMapper O(Params, Path);
+ return O && O.map("threadId", Args.threadId);
+}
+
+json::Value toJSON(const ExceptionInfoResponseBody &ERB) {
+ json::Object result{{"exceptionId", ERB.exceptionId},
+ {"breakMode", ERB.breakMode}};
+
+ if (!ERB.description.empty())
+ result.insert({"description", ERB.description.c_str()});
+ if (ERB.details.has_value())
+ result.insert({"details", *ERB.details});
+
+ return result;
+}
+
} // namespace lldb_dap::protocol
diff --git a/lldb/unittests/DAP/CMakeLists.txt b/lldb/unittests/DAP/CMakeLists.txt
index a08414c30e6cd..434f5280a97a0 100644
--- a/lldb/unittests/DAP/CMakeLists.txt
+++ b/lldb/unittests/DAP/CMakeLists.txt
@@ -7,6 +7,7 @@ add_lldb_unittest(DAPTests
Handler/ContinueTest.cpp
JSONUtilsTest.cpp
LLDBUtilsTest.cpp
+ ProtocolRequestsTest.cpp
ProtocolTypesTest.cpp
ProtocolUtilsTest.cpp
TestBase.cpp
diff --git a/lldb/unittests/DAP/ProtocolRequestsTest.cpp b/lldb/unittests/DAP/ProtocolRequestsTest.cpp
new file mode 100644
index 0000000000000..6b0a794ad72f2
--- /dev/null
+++ b/lldb/unittests/DAP/ProtocolRequestsTest.cpp
@@ -0,0 +1,69 @@
+//===-- ProtocolRequestsTest.cpp ------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "Protocol/ProtocolRequests.h"
+#include "Protocol/ProtocolTypes.h"
+#include "TestingSupport/TestUtilities.h"
+#include "llvm/Testing/Support/Error.h"
+#include <gtest/gtest.h>
+
+using namespace llvm;
+using namespace lldb_dap::protocol;
+using lldb_private::pprint;
+using llvm::json::parse;
+
+TEST(ProtocolRequestsTest, ExceptionInfoArguments) {
+ llvm::Expected<ExceptionInfoArguments> expected =
+ parse<ExceptionInfoArguments>(R"({
+ "threadId": 3434
+ })");
+ ASSERT_THAT_EXPECTED(expected, llvm::Succeeded());
+ EXPECT_EQ(expected->threadId, 3434U);
+
+ // Check required keys;
+ EXPECT_THAT_EXPECTED(parse<ExceptionInfoArguments>(R"({})"),
+ FailedWithMessage("missing value at (root).threadId"));
+
+ EXPECT_THAT_EXPECTED(parse<ExceptionInfoArguments>(R"({"id": 10})"),
+ FailedWithMessage("missing value at (root).threadId"));
+}
+
+TEST(ProtocolRequestsTest, ExceptionInfoResponseBody) {
+ ExceptionInfoResponseBody body;
+ body.exceptionId = "signal";
+ body.breakMode = eExceptionBreakModeAlways;
+
+ // Check required keys.
+ Expected<json::Value> expected = parse(
+ R"({
+ "exceptionId": "signal",
+ "breakMode": "always"
+ })");
+
+ ASSERT_THAT_EXPECTED(expected, llvm::Succeeded());
+ EXPECT_EQ(pprint(*expected), pprint(body));
+
+ // Check optional keys.
+ body.description = "SIGNAL SIGWINCH";
+ body.breakMode = eExceptionBreakModeNever;
+ body.details = ExceptionDetails{};
+ body.details->message = "some message";
+
+ Expected<json::Value> expected_opt = parse(
+ R"({
+ "exceptionId": "signal",
+ "description": "SIGNAL SIGWINCH",
+ "breakMode": "never",
+ "details": {
+ "message": "some message"
+ }
+ })");
+
+ ASSERT_THAT_EXPECTED(expected_opt, llvm::Succeeded());
+ EXPECT_EQ(pprint(*expected_opt), pprint(body));
+}
diff --git a/lldb/unittests/DAP/ProtocolTypesTest.cpp b/lldb/unittests/DAP/ProtocolTypesTest.cpp
index a5ae856a185b7..ee638f8f18cf3 100644
--- a/lldb/unittests/DAP/ProtocolTypesTest.cpp
+++ b/lldb/unittests/DAP/ProtocolTypesTest.cpp
@@ -1126,3 +1126,51 @@ TEST(ProtocolTypesTest, DataBreakpointInfoArguments) {
EXPECT_THAT_EXPECTED(parse<DataBreakpointInfoArguments>(R"({"name":"data"})"),
llvm::Succeeded());
}
+
+TEST(ProtocolTypesTest, ExceptionBreakMode) {
+ const std::vector<std::pair<ExceptionBreakMode, llvm::StringRef>> test_cases =
+ {{ExceptionBreakMode::eExceptionBreakModeAlways, "always"},
+ {ExceptionBreakMode::eExceptionBreakModeNever, "never"},
+ {ExceptionBreakMode::eExceptionBreakModeUnhandled, "unhandled"},
+ {ExceptionBreakMode::eExceptionBreakModeUserUnhandled, "userUnhandled"}};
+
+ for (const auto [value, expected] : test_cases) {
+ json::Value const serialized = toJSON(value);
+ ASSERT_EQ(serialized.kind(), llvm::json::Value::Kind::String);
+ EXPECT_EQ(serialized.getAsString(), expected);
+
+ }
+}
+
+TEST(ProtocolTypesTest, ExceptionDetails) {
+ ExceptionDetails details;
+
+ // Check required keys.
+ Expected<json::Value> expected = parse(R"({})");
+ ASSERT_THAT_EXPECTED(expected, llvm::Succeeded());
+ EXPECT_EQ(pp(*expected), pp(details));
+
+ // Check optional keys.
+ details.message = "SIGABRT exception";
+ details.typeName = "signal";
+ details.fullTypeName = "SIGABRT";
+ details.evaluateName = "process handle SIGABRT";
+ details.stackTrace = "some stacktrace";
+ ExceptionDetails inner_details;
+ inner_details.message = "inner message";
+ details.innerException = {std::move(inner_details)};
+
+ Expected<json::Value> expected_opt = parse(R"({
+ "message": "SIGABRT exception",
+ "typeName": "signal",
+ "fullTypeName": "SIGABRT",
+ "evaluateName": "process handle SIGABRT",
+ "stackTrace": "some stacktrace",
+ "innerException": [{
+ "message": "inner message"
+ }]
+ })");
+
+ ASSERT_THAT_EXPECTED(expected_opt, llvm::Succeeded());
+ EXPECT_EQ(pp(*expected_opt), pp(details));
+}
diff --git a/lldb/unittests/TestingSupport/TestUtilities.cpp b/lldb/unittests/TestingSupport/TestUtilities.cpp
index b53822e38324b..040ad1f8cab54 100644
--- a/lldb/unittests/TestingSupport/TestUtilities.cpp
+++ b/lldb/unittests/TestingSupport/TestUtilities.cpp
@@ -20,6 +20,11 @@ using namespace lldb_private;
extern const char *TestMainArgv0;
std::once_flag TestUtilities::g_debugger_initialize_flag;
+
+std::string lldb_private::pprint(const llvm::json::Value &value) {
+ return llvm::formatv("{0:2}", value).str();
+}
+
std::string lldb_private::GetInputFilePath(const llvm::Twine &name) {
llvm::SmallString<128> result = llvm::sys::path::parent_path(TestMainArgv0);
llvm::sys::fs::make_absolute(result);
diff --git a/lldb/unittests/TestingSupport/TestUtilities.h b/lldb/unittests/TestingSupport/TestUtilities.h
index cc93a68a6a431..751fa415c9a94 100644
--- a/lldb/unittests/TestingSupport/TestUtilities.h
+++ b/lldb/unittests/TestingSupport/TestUtilities.h
@@ -30,6 +30,10 @@
}
namespace lldb_private {
+
+/// Returns a pretty printed json string of a `llvm::json::Value`.
+std::string pprint(const llvm::json::Value &E);
+
std::string GetInputFilePath(const llvm::Twine &name);
class TestUtilities {
>From 6b8bd5e43b9ace5af5de760f2e44a648cd5edf22 Mon Sep 17 00:00:00 2001
From: Ebuka Ezike <yerimyah1 at gmail.com>
Date: Mon, 20 Oct 2025 22:11:06 +0100
Subject: [PATCH 3/4] [lldb-dap] format files
---
lldb/unittests/DAP/ProtocolTypesTest.cpp | 1 -
1 file changed, 1 deletion(-)
diff --git a/lldb/unittests/DAP/ProtocolTypesTest.cpp b/lldb/unittests/DAP/ProtocolTypesTest.cpp
index ee638f8f18cf3..f892d10d75304 100644
--- a/lldb/unittests/DAP/ProtocolTypesTest.cpp
+++ b/lldb/unittests/DAP/ProtocolTypesTest.cpp
@@ -1138,7 +1138,6 @@ TEST(ProtocolTypesTest, ExceptionBreakMode) {
json::Value const serialized = toJSON(value);
ASSERT_EQ(serialized.kind(), llvm::json::Value::Kind::String);
EXPECT_EQ(serialized.getAsString(), expected);
-
}
}
>From b45b5bca5000c3308c24cc020c403d1ae14658a8 Mon Sep 17 00:00:00 2001
From: Ebuka Ezike <yerimyah1 at gmail.com>
Date: Tue, 21 Oct 2025 23:46:50 +0100
Subject: [PATCH 4/4] [lldb-dap] add review changes
---
lldb/tools/lldb-dap/Handler/ExceptionInfoRequestHandler.cpp | 4 ++--
lldb/unittests/DAP/ProtocolRequestsTest.cpp | 6 +++---
lldb/unittests/TestingSupport/TestUtilities.cpp | 2 +-
lldb/unittests/TestingSupport/TestUtilities.h | 2 +-
4 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/lldb/tools/lldb-dap/Handler/ExceptionInfoRequestHandler.cpp b/lldb/tools/lldb-dap/Handler/ExceptionInfoRequestHandler.cpp
index a1aa3865617f0..822bb284b897b 100644
--- a/lldb/tools/lldb-dap/Handler/ExceptionInfoRequestHandler.cpp
+++ b/lldb/tools/lldb-dap/Handler/ExceptionInfoRequestHandler.cpp
@@ -31,13 +31,13 @@ ExceptionInfoRequestHandler::Run(const ExceptionInfoArguments &args) const {
ExceptionInfoResponseBody response;
response.breakMode = eExceptionBreakModeAlways;
- lldb::StopReason stop_reason = thread.GetStopReason();
+ const lldb::StopReason stop_reason = thread.GetStopReason();
switch (stop_reason) {
case lldb::eStopReasonSignal:
response.exceptionId = "signal";
break;
case lldb::eStopReasonBreakpoint: {
- ExceptionBreakpoint *exc_bp = dap.GetExceptionBPFromStopReason(thread);
+ const ExceptionBreakpoint *exc_bp = dap.GetExceptionBPFromStopReason(thread);
if (exc_bp) {
response.exceptionId = exc_bp->GetFilter();
response.description = exc_bp->GetLabel();
diff --git a/lldb/unittests/DAP/ProtocolRequestsTest.cpp b/lldb/unittests/DAP/ProtocolRequestsTest.cpp
index 6b0a794ad72f2..498195dc09325 100644
--- a/lldb/unittests/DAP/ProtocolRequestsTest.cpp
+++ b/lldb/unittests/DAP/ProtocolRequestsTest.cpp
@@ -14,7 +14,7 @@
using namespace llvm;
using namespace lldb_dap::protocol;
-using lldb_private::pprint;
+using lldb_private::PrettyPrint;
using llvm::json::parse;
TEST(ProtocolRequestsTest, ExceptionInfoArguments) {
@@ -46,7 +46,7 @@ TEST(ProtocolRequestsTest, ExceptionInfoResponseBody) {
})");
ASSERT_THAT_EXPECTED(expected, llvm::Succeeded());
- EXPECT_EQ(pprint(*expected), pprint(body));
+ EXPECT_EQ(PrettyPrint(*expected), PrettyPrint(body));
// Check optional keys.
body.description = "SIGNAL SIGWINCH";
@@ -65,5 +65,5 @@ TEST(ProtocolRequestsTest, ExceptionInfoResponseBody) {
})");
ASSERT_THAT_EXPECTED(expected_opt, llvm::Succeeded());
- EXPECT_EQ(pprint(*expected_opt), pprint(body));
+ EXPECT_EQ(PrettyPrint(*expected_opt), PrettyPrint(body));
}
diff --git a/lldb/unittests/TestingSupport/TestUtilities.cpp b/lldb/unittests/TestingSupport/TestUtilities.cpp
index 040ad1f8cab54..d164c227afb9e 100644
--- a/lldb/unittests/TestingSupport/TestUtilities.cpp
+++ b/lldb/unittests/TestingSupport/TestUtilities.cpp
@@ -21,7 +21,7 @@ extern const char *TestMainArgv0;
std::once_flag TestUtilities::g_debugger_initialize_flag;
-std::string lldb_private::pprint(const llvm::json::Value &value) {
+std::string lldb_private::PrettyPrint(const llvm::json::Value &value) {
return llvm::formatv("{0:2}", value).str();
}
diff --git a/lldb/unittests/TestingSupport/TestUtilities.h b/lldb/unittests/TestingSupport/TestUtilities.h
index 751fa415c9a94..f05d176618fa0 100644
--- a/lldb/unittests/TestingSupport/TestUtilities.h
+++ b/lldb/unittests/TestingSupport/TestUtilities.h
@@ -32,7 +32,7 @@
namespace lldb_private {
/// Returns a pretty printed json string of a `llvm::json::Value`.
-std::string pprint(const llvm::json::Value &E);
+std::string PrettyPrint(const llvm::json::Value &E);
std::string GetInputFilePath(const llvm::Twine &name);
More information about the lldb-commits
mailing list