1 | //===-- SetExceptionBreakpointsRequestHandler.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 <set> |
14 | |
15 | namespace lldb_dap { |
16 | |
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(K: "arguments" ); |
70 | const auto *filters = arguments->getArray(K: "filters" ); |
71 | // Keep a list of any exception breakpoint filter names that weren't set |
72 | // so we can clear any exception breakpoints if needed. |
73 | std::set<llvm::StringRef> unset_filters; |
74 | for (const auto &bp : *dap.exception_breakpoints) |
75 | unset_filters.insert(x: bp.GetFilter()); |
76 | |
77 | for (const auto &value : *filters) { |
78 | const auto filter = GetAsString(value); |
79 | auto *exc_bp = dap.GetExceptionBreakpoint(filter); |
80 | if (exc_bp) { |
81 | exc_bp->SetBreakpoint(); |
82 | unset_filters.erase(x: std::string(filter)); |
83 | } |
84 | } |
85 | for (const auto &filter : unset_filters) { |
86 | auto *exc_bp = dap.GetExceptionBreakpoint(filter); |
87 | if (exc_bp) |
88 | exc_bp->ClearBreakpoint(); |
89 | } |
90 | dap.SendJSON(json: llvm::json::Value(std::move(response))); |
91 | } |
92 | |
93 | } // namespace lldb_dap |
94 | |