Skip to content

Commit 19b3a1b

Browse files
committed
restore exception breakpoints
1 parent fd0ce16 commit 19b3a1b

File tree

6 files changed

+59
-188
lines changed

6 files changed

+59
-188
lines changed

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

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -353,18 +353,14 @@ class SetBreakpointsRequestHandler
353353
Run(const protocol::SetBreakpointsArguments &args) const override;
354354
};
355355

356-
class SetExceptionBreakpointsRequestHandler
357-
: public RequestHandler<
358-
protocol::SetExceptionBreakpointsArguments,
359-
llvm::Expected<protocol::SetExceptionBreakpointsResponseBody>> {
356+
class SetExceptionBreakpointsRequestHandler : public LegacyRequestHandler {
360357
public:
361-
using RequestHandler::RequestHandler;
358+
using LegacyRequestHandler::LegacyRequestHandler;
362359
static llvm::StringLiteral GetCommand() { return "setExceptionBreakpoints"; }
363360
FeatureSet GetSupportedFeatures() const override {
364361
return {protocol::eAdapterFeatureExceptionOptions};
365362
}
366-
llvm::Expected<protocol::SetExceptionBreakpointsResponseBody>
367-
Run(const protocol::SetExceptionBreakpointsArguments &args) const override;
363+
void operator()(const llvm::json::Object &request) const override;
368364
};
369365

370366
class SetFunctionBreakpointsRequestHandler

lldb/tools/lldb-dap/Handler/SetExceptionBreakpointsRequestHandler.cpp

Lines changed: 56 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -14,41 +14,80 @@
1414

1515
namespace lldb_dap {
1616

17-
/// The request configures the debugger’s response to thrown exceptions. Each of
18-
/// the `filters`, `filterOptions`, and `exceptionOptions` in the request are
19-
/// independent configurations to a debug adapter indicating a kind of exception
20-
/// to catch. An exception thrown in a program should result in a stopped event
21-
/// from the debug adapter (with reason exception) if any of the configured
22-
/// filters match. Clients should only call this request if the corresponding
23-
/// capability exceptionBreakpointFilters returns one or more filters.
24-
llvm::Expected<protocol::SetExceptionBreakpointsResponseBody>
25-
SetExceptionBreakpointsRequestHandler::Run(
26-
const protocol::SetExceptionBreakpointsArguments &args) const {
27-
std::vector<protocol::Breakpoint> response_breakpoints;
17+
// "SetExceptionBreakpointsRequest": {
18+
// "allOf": [ { "$ref": "#/definitions/Request" }, {
19+
// "type": "object",
20+
// "description": "SetExceptionBreakpoints request; value of command field
21+
// is 'setExceptionBreakpoints'. The request configures the debuggers
22+
// response to thrown exceptions. If an exception is configured to break, a
23+
// StoppedEvent is fired (event type 'exception').", "properties": {
24+
// "command": {
25+
// "type": "string",
26+
// "enum": [ "setExceptionBreakpoints" ]
27+
// },
28+
// "arguments": {
29+
// "$ref": "#/definitions/SetExceptionBreakpointsArguments"
30+
// }
31+
// },
32+
// "required": [ "command", "arguments" ]
33+
// }]
34+
// },
35+
// "SetExceptionBreakpointsArguments": {
36+
// "type": "object",
37+
// "description": "Arguments for 'setExceptionBreakpoints' request.",
38+
// "properties": {
39+
// "filters": {
40+
// "type": "array",
41+
// "items": {
42+
// "type": "string"
43+
// },
44+
// "description": "IDs of checked exception options. The set of IDs is
45+
// returned via the 'exceptionBreakpointFilters' capability."
46+
// },
47+
// "exceptionOptions": {
48+
// "type": "array",
49+
// "items": {
50+
// "$ref": "#/definitions/ExceptionOptions"
51+
// },
52+
// "description": "Configuration options for selected exceptions."
53+
// }
54+
// },
55+
// "required": [ "filters" ]
56+
// },
57+
// "SetExceptionBreakpointsResponse": {
58+
// "allOf": [ { "$ref": "#/definitions/Response" }, {
59+
// "type": "object",
60+
// "description": "Response to 'setExceptionBreakpoints' request. This is
61+
// just an acknowledgement, so no body field is required."
62+
// }]
63+
// }
64+
void SetExceptionBreakpointsRequestHandler::operator()(
65+
const llvm::json::Object &request) const {
66+
llvm::json::Object response;
67+
lldb::SBError error;
68+
FillResponse(request, response);
69+
const auto *arguments = request.getObject("arguments");
70+
const auto *filters = arguments->getArray("filters");
2871
// Keep a list of any exception breakpoint filter names that weren't set
2972
// so we can clear any exception breakpoints if needed.
3073
std::set<llvm::StringRef> unset_filters;
3174
for (const auto &bp : *dap.exception_breakpoints)
3275
unset_filters.insert(bp.GetFilter());
3376

34-
for (const auto &value : args.filters) {
77+
for (const auto &value : *filters) {
3578
const auto filter = GetAsString(value);
3679
auto *exc_bp = dap.GetExceptionBreakpoint(std::string(filter));
37-
protocol::Breakpoint response_bp;
3880
if (exc_bp) {
3981
exc_bp->SetBreakpoint();
4082
unset_filters.erase(std::string(filter));
41-
response_bp.verified = true;
4283
}
43-
response_breakpoints.push_back(response_bp);
4484
}
4585
for (const auto &filter : unset_filters) {
4686
auto *exc_bp = dap.GetExceptionBreakpoint(filter);
4787
if (exc_bp)
4888
exc_bp->ClearBreakpoint();
4989
}
50-
51-
return protocol::SetExceptionBreakpointsResponseBody{response_breakpoints};
90+
dap.SendJSON(llvm::json::Value(std::move(response)));
5291
}
5392

5493
} // namespace lldb_dap

lldb/tools/lldb-dap/Protocol/ProtocolRequests.cpp

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -327,20 +327,6 @@ llvm::json::Value toJSON(const SetFunctionBreakpointsResponseBody &SFBR) {
327327
return result;
328328
}
329329

330-
bool fromJSON(const llvm::json::Value &Params,
331-
SetExceptionBreakpointsArguments &SEBA, llvm::json::Path P) {
332-
json::ObjectMapper O(Params, P);
333-
return O && O.map("filters", SEBA.filters) &&
334-
O.map("filterOptions", SEBA.filterOptions) &&
335-
O.map("exceptionOptions", SEBA.exceptionOptions);
336-
}
337-
338-
llvm::json::Value toJSON(const SetExceptionBreakpointsResponseBody &SEBR) {
339-
json::Object result;
340-
result["breakpoints"] = SEBR.breakpoints;
341-
return result;
342-
}
343-
344330
bool fromJSON(const llvm::json::Value &Params,
345331
SetInstructionBreakpointsArguments &SIBA, llvm::json::Path P) {
346332
json::ObjectMapper O(Params, P);

lldb/tools/lldb-dap/Protocol/ProtocolRequests.h

Lines changed: 0 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -426,54 +426,6 @@ struct SetFunctionBreakpointsResponseBody {
426426
};
427427
llvm::json::Value toJSON(const SetFunctionBreakpointsResponseBody &);
428428

429-
/// Arguments for `setExceptionBreakpoints` request.
430-
struct SetExceptionBreakpointsArguments {
431-
/// Set of exception filters specified by their ID. The set of all possible
432-
/// exception filters is defined by the `exceptionBreakpointFilters`
433-
/// capability. The `filter` and `filterOptions` sets are additive.
434-
std::vector<std::string> filters;
435-
436-
/// Set of exception filters and their options. The set of all possible
437-
/// exception filters is defined by the `exceptionBreakpointFilters`
438-
/// capability. This attribute is only honored by a debug adapter if the
439-
/// corresponding capability `supportsExceptionFilterOptions` is true. The
440-
/// `filter` and `filterOptions` sets are additive.
441-
std::optional<std::vector<ExceptionFilterOptions>> filterOptions;
442-
443-
/// Configuration options for selected exceptions.
444-
/// The attribute is only honored by a debug adapter if the corresponding
445-
/// capability `supportsExceptionOptions` is true.
446-
std::optional<std::vector<ExceptionOptions>> exceptionOptions;
447-
};
448-
bool fromJSON(const llvm::json::Value &, SetExceptionBreakpointsArguments &,
449-
llvm::json::Path);
450-
451-
/// Response to `setExceptionBreakpoints` request.
452-
/// The response contains an array of Breakpoint objects with information about
453-
/// each exception breakpoint or filter. The Breakpoint objects are in the same
454-
/// order as the elements of the filters, filterOptions, exceptionOptions arrays
455-
/// given as arguments. If both filters and filterOptions are given, the
456-
/// returned array must start with filters information first, followed by
457-
/// filterOptions information.
458-
/// The verified property of a Breakpoint object signals whether the exception
459-
/// breakpoint or filter could be successfully created and whether the condition
460-
/// is valid. In case of an error the message property explains the problem. The
461-
/// id property can be used to introduce a unique ID for the exception
462-
/// breakpoint or filter so that it can be updated subsequently by sending
463-
/// breakpoint events. For backward compatibility both the breakpoints array and
464-
/// the enclosing body are optional. If these elements are missing a client is
465-
/// not able to show problems for individual exception breakpoints or filters.
466-
struct SetExceptionBreakpointsResponseBody {
467-
/// Information about the exception breakpoints or filters.
468-
/// The breakpoints returned are in the same order as the elements of the
469-
/// `filters`, `filterOptions`, `exceptionOptions` arrays in the arguments.
470-
/// If both `filters` and `filterOptions` are given, the returned array must
471-
/// start with `filters` information first, followed by `filterOptions`
472-
/// information.
473-
std::vector<Breakpoint> breakpoints;
474-
};
475-
llvm::json::Value toJSON(const SetExceptionBreakpointsResponseBody &);
476-
477429
/// Arguments for `setInstructionBreakpoints` request.
478430
struct SetInstructionBreakpointsArguments {
479431
/// The instruction references of the breakpoints.

lldb/tools/lldb-dap/Protocol/ProtocolTypes.cpp

Lines changed: 0 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -315,47 +315,6 @@ json::Value toJSON(const Breakpoint &BP) {
315315
return result;
316316
}
317317

318-
bool fromJSON(const llvm::json::Value &Params, ExceptionBreakMode &EBM,
319-
llvm::json::Path P) {
320-
auto rawMode = Params.getAsString();
321-
if (!rawMode) {
322-
P.report("expected a string");
323-
return false;
324-
}
325-
std::optional<ExceptionBreakMode> mode =
326-
StringSwitch<std::optional<ExceptionBreakMode>>(*rawMode)
327-
.Case("never", eExceptionBreakModeNever)
328-
.Case("always", eExceptionBreakModeAlways)
329-
.Case("unhandled", eExceptionBreakModeUnhandled)
330-
.Case("userUnhandled", eExceptionBreakModeUserUnhandled)
331-
.Default(std::nullopt);
332-
if (!mode) {
333-
P.report("unexpected ExceptionBreakMode value");
334-
return false;
335-
}
336-
EBM = *mode;
337-
return true;
338-
}
339-
340-
bool fromJSON(const llvm::json::Value &Params, ExceptionPathSegment &EPS,
341-
llvm::json::Path P) {
342-
json::ObjectMapper O(Params, P);
343-
return O && O.map("negate", EPS.negate) && O.map("names", EPS.names);
344-
}
345-
346-
bool fromJSON(const llvm::json::Value &Params, ExceptionOptions &EO,
347-
llvm::json::Path P) {
348-
json::ObjectMapper O(Params, P);
349-
return O && O.map("path", EO.path) && O.map("breakMode", EO.breakMode);
350-
}
351-
352-
bool fromJSON(const llvm::json::Value &Params, ExceptionFilterOptions &EFO,
353-
llvm::json::Path P) {
354-
json::ObjectMapper O(Params, P);
355-
return O && O.map("filterId", EFO.filterId) &&
356-
O.map("condition", EFO.condition) && O.map("mode", EFO.mode);
357-
}
358-
359318
bool fromJSON(const llvm::json::Value &Params, SourceBreakpoint &SB,
360319
llvm::json::Path P) {
361320
json::ObjectMapper O(Params, P);

lldb/tools/lldb-dap/Protocol/ProtocolTypes.h

Lines changed: 0 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -503,67 +503,6 @@ struct InstructionBreakpoint {
503503
bool fromJSON(const llvm::json::Value &, InstructionBreakpoint &,
504504
llvm::json::Path);
505505

506-
/// An ExceptionFilterOptions is used to specify an exception filter together
507-
/// with a condition for the `setExceptionBreakpoints` request.
508-
struct ExceptionFilterOptions {
509-
/// ID of an exception filter returned by the `exceptionBreakpointFilters`
510-
/// capability.
511-
std::string filterId;
512-
513-
/// An expression for conditional exceptions.
514-
/// The exception breaks into the debugger if the result of the condition is
515-
/// true.
516-
std::optional<std::string> condition;
517-
518-
/// The mode of this exception breakpoint. If defined, this must be one of the
519-
/// `breakpointModes` the debug adapter advertised in its `Capabilities`.
520-
std::optional<std::string> mode;
521-
};
522-
bool fromJSON(const llvm::json::Value &, ExceptionFilterOptions &,
523-
llvm::json::Path);
524-
525-
/// This enumeration defines all possible conditions when a thrown exception
526-
/// should result in a break.
527-
enum ExceptionBreakMode : unsigned {
528-
/// Never breaks.
529-
eExceptionBreakModeNever,
530-
/// Always breaks.
531-
eExceptionBreakModeAlways,
532-
/// Breaks when the exception is unhandled.
533-
eExceptionBreakModeUnhandled,
534-
/// Breaks if the exception is not handled by user code.
535-
eExceptionBreakModeUserUnhandled
536-
};
537-
bool fromJSON(const llvm::json::Value &, ExceptionBreakMode &,
538-
llvm::json::Path);
539-
540-
/// An ExceptionPathSegment represents a segment in a path that is used to
541-
/// match leafs or nodes in a tree of exceptions.
542-
struct ExceptionPathSegment {
543-
/// If false or missing, this segment matches the names provided. Otherwise,
544-
/// it matches anything except the names provided.
545-
std::optional<bool> negate;
546-
547-
/// Depending on the value of `negate`, the names that should match or not
548-
/// match.
549-
std::vector<std::string> names;
550-
};
551-
bool fromJSON(const llvm::json::Value &, ExceptionPathSegment &,
552-
llvm::json::Path);
553-
554-
/// ExceptionOptions assigns configuration options to a set of exceptions.
555-
struct ExceptionOptions {
556-
/// A path that selects a single or multiple exceptions in a tree. If `path`
557-
/// is missing, the whole tree is selected.
558-
/// By convention, the first segment of the path is a category that is used
559-
/// to group exceptions in the UI.
560-
std::optional<std::vector<ExceptionPathSegment>> path;
561-
562-
/// Condition when a thrown exception should result in a break.
563-
ExceptionBreakMode breakMode;
564-
};
565-
bool fromJSON(const llvm::json::Value &, ExceptionOptions &, llvm::json::Path);
566-
567506
} // namespace lldb_dap::protocol
568507

569508
#endif

0 commit comments

Comments
 (0)