[Lldb-commits] [lldb] Revert "[lldb-dap] Use protocol types for exceptioninfo" (PR #164631)
via lldb-commits
lldb-commits at lists.llvm.org
Wed Oct 22 07:22:25 PDT 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-lldb
Author: Walter Lee (googlewalt)
<details>
<summary>Changes</summary>
Reverts llvm/llvm-project#<!-- -->164318
2 failures from LLVM Buildbot.
---
Patch is 20.33 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/164631.diff
11 Files Affected:
- (modified) lldb/tools/lldb-dap/Handler/ExceptionInfoRequestHandler.cpp (+151-60)
- (modified) lldb/tools/lldb-dap/Handler/RequestHandler.h (+3-7)
- (modified) lldb/tools/lldb-dap/Protocol/ProtocolRequests.cpp (-18)
- (modified) lldb/tools/lldb-dap/Protocol/ProtocolRequests.h (-22)
- (modified) lldb/tools/lldb-dap/Protocol/ProtocolTypes.cpp (-33)
- (modified) lldb/tools/lldb-dap/Protocol/ProtocolTypes.h (-30)
- (modified) lldb/unittests/DAP/CMakeLists.txt (-1)
- (removed) lldb/unittests/DAP/ProtocolRequestsTest.cpp (-69)
- (modified) lldb/unittests/DAP/ProtocolTypesTest.cpp (-47)
- (modified) lldb/unittests/TestingSupport/TestUtilities.cpp (-5)
- (modified) lldb/unittests/TestingSupport/TestUtilities.h (-4)
``````````diff
diff --git a/lldb/tools/lldb-dap/Handler/ExceptionInfoRequestHandler.cpp b/lldb/tools/lldb-dap/Handler/ExceptionInfoRequestHandler.cpp
index fa01a2036e1dd..c1c2adb32a510 100644
--- a/lldb/tools/lldb-dap/Handler/ExceptionInfoRequestHandler.cpp
+++ b/lldb/tools/lldb-dap/Handler/ExceptionInfoRequestHandler.cpp
@@ -7,77 +7,168 @@
//===----------------------------------------------------------------------===//
#include "DAP.h"
-#include "DAPError.h"
-#include "Protocol/ProtocolRequests.h"
-#include "Protocol/ProtocolTypes.h"
+#include "EventHelper.h"
+#include "JSONUtils.h"
#include "RequestHandler.h"
#include "lldb/API/SBStream.h"
-using namespace lldb_dap::protocol;
-
namespace lldb_dap {
-/// 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;
- const lldb::StopReason stop_reason = thread.GetStopReason();
- switch (stop_reason) {
- case lldb::eStopReasonSignal:
- response.exceptionId = "signal";
- break;
- case lldb::eStopReasonBreakpoint: {
- const ExceptionBreakpoint *exc_bp =
- dap.GetExceptionBPFromStopReason(thread);
- if (exc_bp) {
- response.exceptionId = exc_bp->GetFilter();
- response.description = exc_bp->GetLabel();
+// "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");
+ }
} else {
- response.exceptionId = "exception";
- }
- } 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("exceptionId", "exception");
}
- }
-
- if (lldb::SBValue exception = thread.GetCurrentException()) {
- lldb::SBStream stream;
- response.details = ExceptionDetails{};
- if (exception.GetDescription(stream)) {
- response.details->message = stream.GetData();
+ if (!ObjectContainsKey(body, "description")) {
+ char description[1024];
+ if (thread.GetStopDescription(description, sizeof(description))) {
+ EmplaceSafeString(body, "description", description);
+ }
}
+ 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());
+ }
- if (lldb::SBThread exception_backtrace =
- thread.GetCurrentExceptionBacktrace()) {
- stream.Clear();
- exception_backtrace.GetDescription(stream);
-
- for (uint32_t idx = 0; idx < exception_backtrace.GetNumFrames(); idx++) {
- lldb::SBFrame frame = exception_backtrace.GetFrameAtIndex(idx);
- frame.GetDescription(stream);
+ 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());
}
- response.details->stackTrace = stream.GetData();
+
+ body.try_emplace("details", std::move(details));
}
+ // 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);
}
- return response;
+ response.try_emplace("body", std::move(body));
+ dap.SendJSON(llvm::json::Value(std::move(response)));
}
} // namespace lldb_dap
diff --git a/lldb/tools/lldb-dap/Handler/RequestHandler.h b/lldb/tools/lldb-dap/Handler/RequestHandler.h
index 7a7e1263c66f4..977a247996750 100644
--- a/lldb/tools/lldb-dap/Handler/RequestHandler.h
+++ b/lldb/tools/lldb-dap/Handler/RequestHandler.h
@@ -302,18 +302,14 @@ class EvaluateRequestHandler : public LegacyRequestHandler {
}
};
-class ExceptionInfoRequestHandler
- : public RequestHandler<
- protocol::ExceptionInfoArguments,
- llvm::Expected<protocol::ExceptionInfoResponseBody>> {
+class ExceptionInfoRequestHandler : public LegacyRequestHandler {
public:
- using RequestHandler::RequestHandler;
+ using LegacyRequestHandler::LegacyRequestHandler;
static llvm::StringLiteral GetCommand() { return "exceptionInfo"; }
FeatureSet GetSupportedFeatures() const override {
return {protocol::eAdapterFeatureExceptionInfoRequest};
}
- llvm::Expected<protocol::ExceptionInfoResponseBody>
- Run(const protocol::ExceptionInfoArguments &args) const override;
+ void operator()(const llvm::json::Object &request) const override;
};
class InitializeRequestHandler
diff --git a/lldb/tools/lldb-dap/Protocol/ProtocolRequests.cpp b/lldb/tools/lldb-dap/Protocol/ProtocolRequests.cpp
index e207aad2167d6..b9393356b4e01 100644
--- a/lldb/tools/lldb-dap/Protocol/ProtocolRequests.cpp
+++ b/lldb/tools/lldb-dap/Protocol/ProtocolRequests.cpp
@@ -625,22 +625,4 @@ 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/tools/lldb-dap/Protocol/ProtocolRequests.h b/lldb/tools/lldb-dap/Protocol/ProtocolRequests.h
index 53e551ac2ec64..a85a68b87014c 100644
--- a/lldb/tools/lldb-dap/Protocol/ProtocolRequests.h
+++ b/lldb/tools/lldb-dap/Protocol/ProtocolRequests.h
@@ -1039,28 +1039,6 @@ 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 95007013742a0..dc8edaadcd9bb 100644
--- a/lldb/tools/lldb-dap/Protocol/ProtocolTypes.cpp
+++ b/lldb/tools/lldb-dap/Protocol/ProtocolTypes.cpp
@@ -1136,37 +1136,4 @@ 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 6d85c74377bd3..7077df90a85b5 100644
--- a/lldb/tools/lldb-dap/Protocol/ProtocolTypes.h
+++ b/lldb/tools/lldb-dap/Protocol/ProtocolTypes.h
@@ -1007,36 +1007,6 @@ 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
diff --git a/lldb/unittests/DAP/CMakeLists.txt b/lldb/unittests/DAP/CMakeLists.txt
index 434f5280a97a0..a08414c30e6cd 100644
--- a/lldb/unittests/DAP/CMakeLists.txt
+++ b/lldb/unittests/DAP/CMakeLists.txt
@@ -7,7 +7,6 @@ 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
deleted file mode 100644
index 498195dc09325..0000000000000
--- a/lldb/unittests/DAP/ProtocolRequestsTest.cpp
+++ /dev/null
@@ -1,69 +0,0 @@
-//===-- 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::PrettyPrint;
-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(PrettyPrint(*expected), PrettyPrint(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(PrettyPrint(*expected_opt), PrettyPrint(body));
-}
diff --git a/lldb/unittests/DAP/ProtocolTypesTest.cpp b/lldb/unittests/DAP/ProtocolTypesTest.cpp
index 6a4620a3f1e59..8170abdd25bc6 100644
--- a/lldb/unittests/DAP/ProtocolTypesTest.cpp
+++ b/lldb/unittests/DAP/ProtocolTypesTest.cpp
@@ -1129,50 +1129,3 @@ 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 d164c227afb9e..b53822e38324b 100644
--- a/lldb/unittests/TestingSupport/TestUtilities.cpp
+++ b/lldb/unittests/TestingSupport/TestUtilities.cpp
@@ -20,11 +20,6 @@ using namespace lldb_private;
extern const char *TestMainArgv0;
std::once_flag TestUtilities::g_debugger_initialize_flag;
-
-std::string lldb_private::PrettyPrint(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 f05d176618fa0..cc93a68a6a431 100644
--- a/lldb/unittests/Tes...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/164631
More information about the lldb-commits
mailing list