Skip to content

Commit a8d212d

Browse files
committed
Adopt ExceptionInfoRequestHandler
1 parent dfb3b0c commit a8d212d

File tree

4 files changed

+183
-160
lines changed

4 files changed

+183
-160
lines changed

lldb/tools/lldb-dap/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ add_lldb_tool(lldb-dap
4444
Handler/ContinueRequestHandler.cpp
4545
Handler/DisconnectRequestHandler.cpp
4646
Handler/EvaluateRequestHandler.cpp
47+
Handler/ExceptionInfoRequestHandler.cpp
4748
Handler/RequestHandler.cpp
4849

4950
LINK_LIBS
Lines changed: 174 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,174 @@
1+
//===-- ExceptionInfoRequestHandler.cpp -----------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#include "DAP.h"
10+
#include "EventHelper.h"
11+
#include "JSONUtils.h"
12+
#include "RequestHandler.h"
13+
#include "lldb/API/SBStream.h"
14+
15+
namespace lldb_dap {
16+
17+
// "ExceptionInfoRequest": {
18+
// "allOf": [ { "$ref": "#/definitions/Request" }, {
19+
// "type": "object",
20+
// "description": "Retrieves the details of the exception that
21+
// caused this event to be raised. Clients should only call this request if
22+
// the corresponding capability `supportsExceptionInfoRequest` is true.",
23+
// "properties": {
24+
// "command": {
25+
// "type": "string",
26+
// "enum": [ "exceptionInfo" ]
27+
// },
28+
// "arguments": {
29+
// "$ref": "#/definitions/ExceptionInfoArguments"
30+
// }
31+
// },
32+
// "required": [ "command", "arguments" ]
33+
// }]
34+
// },
35+
// "ExceptionInfoArguments": {
36+
// "type": "object",
37+
// "description": "Arguments for `exceptionInfo` request.",
38+
// "properties": {
39+
// "threadId": {
40+
// "type": "integer",
41+
// "description": "Thread for which exception information should be
42+
// retrieved."
43+
// }
44+
// },
45+
// "required": [ "threadId" ]
46+
// },
47+
// "ExceptionInfoResponse": {
48+
// "allOf": [ { "$ref": "#/definitions/Response" }, {
49+
// "type": "object",
50+
// "description": "Response to `exceptionInfo` request.",
51+
// "properties": {
52+
// "body": {
53+
// "type": "object",
54+
// "properties": {
55+
// "exceptionId": {
56+
// "type": "string",
57+
// "description": "ID of the exception that was thrown."
58+
// },
59+
// "description": {
60+
// "type": "string",
61+
// "description": "Descriptive text for the exception."
62+
// },
63+
// "breakMode": {
64+
// "$ref": "#/definitions/ExceptionBreakMode",
65+
// "description": "Mode that caused the exception notification to
66+
// be raised."
67+
// },
68+
// "details": {
69+
// "$ref": "#/definitions/ExceptionDetails",
70+
// "description": "Detailed information about the exception."
71+
// }
72+
// },
73+
// "required": [ "exceptionId", "breakMode" ]
74+
// }
75+
// },
76+
// "required": [ "body" ]
77+
// }]
78+
// }
79+
// "ExceptionDetails": {
80+
// "type": "object",
81+
// "description": "Detailed information about an exception that has
82+
// occurred.", "properties": {
83+
// "message": {
84+
// "type": "string",
85+
// "description": "Message contained in the exception."
86+
// },
87+
// "typeName": {
88+
// "type": "string",
89+
// "description": "Short type name of the exception object."
90+
// },
91+
// "fullTypeName": {
92+
// "type": "string",
93+
// "description": "Fully-qualified type name of the exception object."
94+
// },
95+
// "evaluateName": {
96+
// "type": "string",
97+
// "description": "An expression that can be evaluated in the current
98+
// scope to obtain the exception object."
99+
// },
100+
// "stackTrace": {
101+
// "type": "string",
102+
// "description": "Stack trace at the time the exception was thrown."
103+
// },
104+
// "innerException": {
105+
// "type": "array",
106+
// "items": {
107+
// "$ref": "#/definitions/ExceptionDetails"
108+
// },
109+
// "description": "Details of the exception contained by this exception,
110+
// if any."
111+
// }
112+
// }
113+
// },
114+
void ExceptionInfoRequestHandler::operator()(
115+
const llvm::json::Object &request) {
116+
llvm::json::Object response;
117+
FillResponse(request, response);
118+
const auto *arguments = request.getObject("arguments");
119+
llvm::json::Object body;
120+
lldb::SBThread thread = dap.GetLLDBThread(*arguments);
121+
if (thread.IsValid()) {
122+
auto stopReason = thread.GetStopReason();
123+
if (stopReason == lldb::eStopReasonSignal)
124+
body.try_emplace("exceptionId", "signal");
125+
else if (stopReason == lldb::eStopReasonBreakpoint) {
126+
ExceptionBreakpoint *exc_bp = dap.GetExceptionBPFromStopReason(thread);
127+
if (exc_bp) {
128+
EmplaceSafeString(body, "exceptionId", exc_bp->filter);
129+
EmplaceSafeString(body, "description", exc_bp->label);
130+
} else {
131+
body.try_emplace("exceptionId", "exception");
132+
}
133+
} else {
134+
body.try_emplace("exceptionId", "exception");
135+
}
136+
if (!ObjectContainsKey(body, "description")) {
137+
char description[1024];
138+
if (thread.GetStopDescription(description, sizeof(description))) {
139+
EmplaceSafeString(body, "description", std::string(description));
140+
}
141+
}
142+
body.try_emplace("breakMode", "always");
143+
auto exception = thread.GetCurrentException();
144+
if (exception.IsValid()) {
145+
llvm::json::Object details;
146+
lldb::SBStream stream;
147+
if (exception.GetDescription(stream)) {
148+
EmplaceSafeString(details, "message", stream.GetData());
149+
}
150+
151+
auto exceptionBacktrace = thread.GetCurrentExceptionBacktrace();
152+
if (exceptionBacktrace.IsValid()) {
153+
lldb::SBStream stream;
154+
exceptionBacktrace.GetDescription(stream);
155+
for (uint32_t i = 0; i < exceptionBacktrace.GetNumFrames(); i++) {
156+
lldb::SBFrame frame = exceptionBacktrace.GetFrameAtIndex(i);
157+
frame.GetDescription(stream);
158+
}
159+
EmplaceSafeString(details, "stackTrace", stream.GetData());
160+
}
161+
162+
body.try_emplace("details", std::move(details));
163+
}
164+
// auto excInfoCount = thread.GetStopReasonDataCount();
165+
// for (auto i=0; i<excInfoCount; ++i) {
166+
// uint64_t exc_data = thread.GetStopReasonDataAtIndex(i);
167+
// }
168+
} else {
169+
response["success"] = llvm::json::Value(false);
170+
}
171+
response.try_emplace("body", std::move(body));
172+
dap.SendJSON(llvm::json::Value(std::move(response)));
173+
}
174+
} // namespace lldb_dap

lldb/tools/lldb-dap/Handler/RequestHandler.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,13 @@ class EvaluateRequestHandler : public RequestHandler {
8888
void operator()(const llvm::json::Object &request) override;
8989
};
9090

91+
class ExceptionInfoRequestHandler : public RequestHandler {
92+
public:
93+
using RequestHandler::RequestHandler;
94+
static llvm::StringLiteral getCommand() { return "exceptionInfo"; }
95+
void operator()(const llvm::json::Object &request) override;
96+
};
97+
9198
} // namespace lldb_dap
9299

93100
#endif

lldb/tools/lldb-dap/lldb-dap.cpp

Lines changed: 1 addition & 160 deletions
Original file line numberDiff line numberDiff line change
@@ -545,165 +545,6 @@ bool FillStackFrames(DAP &dap, lldb::SBThread &thread,
545545
return reached_end_of_stack;
546546
}
547547

548-
// "ExceptionInfoRequest": {
549-
// "allOf": [ { "$ref": "#/definitions/Request" }, {
550-
// "type": "object",
551-
// "description": "Retrieves the details of the exception that
552-
// caused this event to be raised. Clients should only call this request if
553-
// the corresponding capability `supportsExceptionInfoRequest` is true.",
554-
// "properties": {
555-
// "command": {
556-
// "type": "string",
557-
// "enum": [ "exceptionInfo" ]
558-
// },
559-
// "arguments": {
560-
// "$ref": "#/definitions/ExceptionInfoArguments"
561-
// }
562-
// },
563-
// "required": [ "command", "arguments" ]
564-
// }]
565-
// },
566-
// "ExceptionInfoArguments": {
567-
// "type": "object",
568-
// "description": "Arguments for `exceptionInfo` request.",
569-
// "properties": {
570-
// "threadId": {
571-
// "type": "integer",
572-
// "description": "Thread for which exception information should be
573-
// retrieved."
574-
// }
575-
// },
576-
// "required": [ "threadId" ]
577-
// },
578-
// "ExceptionInfoResponse": {
579-
// "allOf": [ { "$ref": "#/definitions/Response" }, {
580-
// "type": "object",
581-
// "description": "Response to `exceptionInfo` request.",
582-
// "properties": {
583-
// "body": {
584-
// "type": "object",
585-
// "properties": {
586-
// "exceptionId": {
587-
// "type": "string",
588-
// "description": "ID of the exception that was thrown."
589-
// },
590-
// "description": {
591-
// "type": "string",
592-
// "description": "Descriptive text for the exception."
593-
// },
594-
// "breakMode": {
595-
// "$ref": "#/definitions/ExceptionBreakMode",
596-
// "description": "Mode that caused the exception notification to
597-
// be raised."
598-
// },
599-
// "details": {
600-
// "$ref": "#/definitions/ExceptionDetails",
601-
// "description": "Detailed information about the exception."
602-
// }
603-
// },
604-
// "required": [ "exceptionId", "breakMode" ]
605-
// }
606-
// },
607-
// "required": [ "body" ]
608-
// }]
609-
// }
610-
// "ExceptionDetails": {
611-
// "type": "object",
612-
// "description": "Detailed information about an exception that has
613-
// occurred.", "properties": {
614-
// "message": {
615-
// "type": "string",
616-
// "description": "Message contained in the exception."
617-
// },
618-
// "typeName": {
619-
// "type": "string",
620-
// "description": "Short type name of the exception object."
621-
// },
622-
// "fullTypeName": {
623-
// "type": "string",
624-
// "description": "Fully-qualified type name of the exception object."
625-
// },
626-
// "evaluateName": {
627-
// "type": "string",
628-
// "description": "An expression that can be evaluated in the current
629-
// scope to obtain the exception object."
630-
// },
631-
// "stackTrace": {
632-
// "type": "string",
633-
// "description": "Stack trace at the time the exception was thrown."
634-
// },
635-
// "innerException": {
636-
// "type": "array",
637-
// "items": {
638-
// "$ref": "#/definitions/ExceptionDetails"
639-
// },
640-
// "description": "Details of the exception contained by this exception,
641-
// if any."
642-
// }
643-
// }
644-
// },
645-
void request_exceptionInfo(DAP &dap, const llvm::json::Object &request) {
646-
llvm::json::Object response;
647-
FillResponse(request, response);
648-
const auto *arguments = request.getObject("arguments");
649-
llvm::json::Object body;
650-
lldb::SBThread thread = dap.GetLLDBThread(*arguments);
651-
if (thread.IsValid()) {
652-
auto stopReason = thread.GetStopReason();
653-
if (stopReason == lldb::eStopReasonSignal)
654-
body.try_emplace("exceptionId", "signal");
655-
else if (stopReason == lldb::eStopReasonBreakpoint) {
656-
ExceptionBreakpoint *exc_bp = dap.GetExceptionBPFromStopReason(thread);
657-
if (exc_bp) {
658-
EmplaceSafeString(body, "exceptionId", exc_bp->filter);
659-
EmplaceSafeString(body, "description", exc_bp->label);
660-
} else {
661-
body.try_emplace("exceptionId", "exception");
662-
}
663-
} else {
664-
body.try_emplace("exceptionId", "exception");
665-
}
666-
if (!ObjectContainsKey(body, "description")) {
667-
char description[1024];
668-
if (thread.GetStopDescription(description, sizeof(description))) {
669-
EmplaceSafeString(body, "description", std::string(description));
670-
}
671-
}
672-
body.try_emplace("breakMode", "always");
673-
auto exception = thread.GetCurrentException();
674-
if (exception.IsValid()) {
675-
llvm::json::Object details;
676-
lldb::SBStream stream;
677-
if (exception.GetDescription(stream)) {
678-
EmplaceSafeString(details, "message", stream.GetData());
679-
}
680-
681-
auto exceptionBacktrace = thread.GetCurrentExceptionBacktrace();
682-
if (exceptionBacktrace.IsValid()) {
683-
lldb::SBStream stream;
684-
exceptionBacktrace.GetDescription(stream);
685-
for (uint32_t i = 0; i < exceptionBacktrace.GetNumFrames(); i++) {
686-
lldb::SBFrame frame = exceptionBacktrace.GetFrameAtIndex(i);
687-
frame.GetDescription(stream);
688-
}
689-
EmplaceSafeString(details, "stackTrace", stream.GetData());
690-
}
691-
692-
body.try_emplace("details", std::move(details));
693-
}
694-
// auto excInfoCount = thread.GetStopReasonDataCount();
695-
// for (auto i=0; i<excInfoCount; ++i) {
696-
// uint64_t exc_data = thread.GetStopReasonDataAtIndex(i);
697-
// }
698-
} else {
699-
response["success"] = llvm::json::Value(false);
700-
}
701-
response.try_emplace("body", std::move(body));
702-
dap.SendJSON(llvm::json::Value(std::move(response)));
703-
}
704-
705-
706-
707548
// "compileUnitsRequest": {
708549
// "allOf": [ { "$ref": "#/definitions/Request" }, {
709550
// "type": "object",
@@ -3838,8 +3679,8 @@ void RegisterRequestCallbacks(DAP &dap) {
38383679
dap.RegisterRequest<ConfigurationDoneRequestHandler>();
38393680
dap.RegisterRequest<DisconnectRequestHandler>();
38403681
dap.RegisterRequest<EvaluateRequestHandler>();
3682+
dap.RegisterRequest<ExceptionInfoRequestHandler>();
38413683

3842-
dap.RegisterRequestCallback("exceptionInfo", request_exceptionInfo);
38433684
dap.RegisterRequestCallback("initialize", request_initialize);
38443685
dap.RegisterRequestCallback("launch", request_launch);
38453686
dap.RegisterRequestCallback("next", request_next);

0 commit comments

Comments
 (0)