1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
|
//===-- Request.h ---------------------------------------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//
#ifndef LLDB_TOOLS_LLDB_DAP_HANDLER_HANDLER_H
#define LLDB_TOOLS_LLDB_DAP_HANDLER_HANDLER_H
#include "DAP.h"
#include "DAPError.h"
#include "DAPLog.h"
#include "Protocol/ProtocolBase.h"
#include "Protocol/ProtocolRequests.h"
#include "Protocol/ProtocolTypes.h"
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/JSON.h"
#include <optional>
#include <type_traits>
#include <variant>
#include <vector>
template <typename T> struct is_optional : std::false_type {};
template <typename T> struct is_optional<std::optional<T>> : std::true_type {};
template <typename T>
inline constexpr bool is_optional_v = is_optional<T>::value;
namespace lldb_dap {
struct DAP;
/// Base class for request handlers. Do not extend this directly: Extend
/// the RequestHandler template subclass instead.
class BaseRequestHandler {
public:
BaseRequestHandler(DAP &dap) : dap(dap) {}
/// BaseRequestHandler are not copyable.
/// @{
BaseRequestHandler(const BaseRequestHandler &) = delete;
BaseRequestHandler &operator=(const BaseRequestHandler &) = delete;
/// @}
virtual ~BaseRequestHandler() = default;
void Run(const protocol::Request &);
virtual void operator()(const protocol::Request &request) const = 0;
using FeatureSet = llvm::SmallDenseSet<AdapterFeature, 1>;
virtual FeatureSet GetSupportedFeatures() const { return {}; }
protected:
/// Helpers used by multiple request handlers.
/// FIXME: Move these into the DAP class?
/// @{
/// Prints a welcome message on the editor if the preprocessor variable
/// LLDB_DAP_WELCOME_MESSAGE is defined.
void PrintWelcomeMessage() const;
// Takes a LaunchRequest object and launches the process, also handling
// runInTerminal if applicable. It doesn't do any of the additional
// initialization and bookkeeping stuff that is needed for `request_launch`.
// This way we can reuse the process launching logic for RestartRequest too.
llvm::Error
LaunchProcess(const protocol::LaunchRequestArguments &request) const;
// Check if the step-granularity is `instruction`.
bool HasInstructionGranularity(const llvm::json::Object &request) const;
/// @}
DAP &dap;
};
/// FIXME: Migrate callers to typed RequestHandler for improved type handling.
class LegacyRequestHandler : public BaseRequestHandler {
using BaseRequestHandler::BaseRequestHandler;
virtual void operator()(const llvm::json::Object &request) const = 0;
void operator()(const protocol::Request &request) const override {
auto req = toJSON(request);
(*this)(*req.getAsObject());
}
};
template <typename Args>
llvm::Expected<Args> parseArgs(const protocol::Request &request) {
if (!is_optional_v<Args> && !request.arguments)
return llvm::make_error<DAPError>(
llvm::formatv("arguments required for command '{0}' "
"but none received",
request.command)
.str());
Args arguments;
llvm::json::Path::Root root("arguments");
if (request.arguments && !fromJSON(*request.arguments, arguments, root)) {
std::string parse_failure;
llvm::raw_string_ostream OS(parse_failure);
OS << "invalid arguments for request '" << request.command
<< "': " << llvm::toString(root.getError()) << "\n";
root.printErrorContext(*request.arguments, OS);
return llvm::make_error<DAPError>(parse_failure);
}
return arguments;
}
template <>
inline llvm::Expected<protocol::EmptyArguments>
parseArgs(const protocol::Request &request) {
return std::nullopt;
}
/// Base class for handling DAP requests. Handlers should declare their
/// arguments and response body types like:
///
/// class MyRequestHandler : public RequestHandler<Arguments, Response> {
/// ....
/// };
template <typename Args, typename Resp>
class RequestHandler : public BaseRequestHandler {
using BaseRequestHandler::BaseRequestHandler;
void operator()(const protocol::Request &request) const override {
protocol::Response response;
response.request_seq = request.seq;
response.command = request.command;
llvm::Expected<Args> arguments = parseArgs<Args>(request);
if (llvm::Error err = arguments.takeError()) {
HandleErrorResponse(std::move(err), response);
dap.Send(response);
return;
}
if constexpr (std::is_same_v<Resp, llvm::Error>) {
if (llvm::Error err = Run(*arguments)) {
HandleErrorResponse(std::move(err), response);
} else {
response.success = true;
}
} else {
Resp body = Run(*arguments);
if (llvm::Error err = body.takeError()) {
HandleErrorResponse(std::move(err), response);
} else {
response.success = true;
response.body = std::move(*body);
}
}
// Mark the request as 'cancelled' if the debugger was interrupted while
// evaluating this handler.
if (dap.debugger.InterruptRequested()) {
dap.debugger.CancelInterruptRequest();
response.success = false;
response.message = protocol::eResponseMessageCancelled;
response.body = std::nullopt;
}
dap.Send(response);
PostRun();
};
virtual Resp Run(const Args &) const = 0;
/// A hook for a request handler to run additional operations after the
/// request response is sent but before the next request handler.
///
/// *NOTE*: PostRun will be invoked even if the `Run` operation returned an
/// error.
virtual void PostRun() const {};
void HandleErrorResponse(llvm::Error err,
protocol::Response &response) const {
response.success = false;
llvm::handleAllErrors(
std::move(err),
[&](const NotStoppedError &err) {
response.message = lldb_dap::protocol::eResponseMessageNotStopped;
},
[&](const DAPError &err) {
protocol::ErrorMessage error_message;
error_message.sendTelemetry = false;
error_message.format = err.getMessage();
error_message.showUser = err.getShowUser();
error_message.id = err.convertToErrorCode().value();
error_message.url = err.getURL();
error_message.urlLabel = err.getURLLabel();
protocol::ErrorResponseBody body;
body.error = error_message;
response.body = body;
},
[&](const llvm::ErrorInfoBase &err) {
protocol::ErrorMessage error_message;
error_message.showUser = true;
error_message.sendTelemetry = false;
error_message.format = err.message();
error_message.id = err.convertToErrorCode().value();
protocol::ErrorResponseBody body;
body.error = error_message;
response.body = body;
});
}
};
class AttachRequestHandler
: public RequestHandler<protocol::AttachRequestArguments,
protocol::AttachResponse> {
public:
using RequestHandler::RequestHandler;
static llvm::StringLiteral GetCommand() { return "attach"; }
llvm::Error Run(const protocol::AttachRequestArguments &args) const override;
void PostRun() const override;
};
class BreakpointLocationsRequestHandler
: public RequestHandler<
protocol::BreakpointLocationsArguments,
llvm::Expected<protocol::BreakpointLocationsResponseBody>> {
public:
using RequestHandler::RequestHandler;
static llvm::StringLiteral GetCommand() { return "breakpointLocations"; }
FeatureSet GetSupportedFeatures() const override {
return {protocol::eAdapterFeatureBreakpointLocationsRequest};
}
llvm::Expected<protocol::BreakpointLocationsResponseBody>
Run(const protocol::BreakpointLocationsArguments &args) const override;
std::vector<std::pair<uint32_t, uint32_t>>
GetSourceBreakpointLocations(std::string path, uint32_t start_line,
uint32_t start_column, uint32_t end_line,
uint32_t end_column) const;
std::vector<std::pair<uint32_t, uint32_t>>
GetAssemblyBreakpointLocations(int64_t source_reference, uint32_t start_line,
uint32_t end_line) const;
};
class CompletionsRequestHandler
: public RequestHandler<protocol::CompletionsArguments,
llvm::Expected<protocol::CompletionsResponseBody>> {
public:
using RequestHandler::RequestHandler;
static llvm::StringLiteral GetCommand() { return "completions"; }
FeatureSet GetSupportedFeatures() const override {
return {protocol::eAdapterFeatureCompletionsRequest};
}
llvm::Expected<protocol::CompletionsResponseBody>
Run(const protocol::CompletionsArguments &args) const override;
};
class ContinueRequestHandler
: public RequestHandler<protocol::ContinueArguments,
llvm::Expected<protocol::ContinueResponseBody>> {
public:
using RequestHandler::RequestHandler;
static llvm::StringLiteral GetCommand() { return "continue"; }
llvm::Expected<protocol::ContinueResponseBody>
Run(const protocol::ContinueArguments &args) const override;
};
class ConfigurationDoneRequestHandler
: public RequestHandler<protocol::ConfigurationDoneArguments,
protocol::ConfigurationDoneResponse> {
public:
using RequestHandler::RequestHandler;
static llvm::StringLiteral GetCommand() { return "configurationDone"; }
FeatureSet GetSupportedFeatures() const override {
return {protocol::eAdapterFeatureConfigurationDoneRequest};
}
protocol::ConfigurationDoneResponse
Run(const protocol::ConfigurationDoneArguments &) const override;
};
class DisconnectRequestHandler
: public RequestHandler<std::optional<protocol::DisconnectArguments>,
protocol::DisconnectResponse> {
public:
using RequestHandler::RequestHandler;
static llvm::StringLiteral GetCommand() { return "disconnect"; }
FeatureSet GetSupportedFeatures() const override {
return {protocol::eAdapterFeatureTerminateDebuggee};
}
llvm::Error
Run(const std::optional<protocol::DisconnectArguments> &args) const override;
};
class EvaluateRequestHandler : public LegacyRequestHandler {
public:
using LegacyRequestHandler::LegacyRequestHandler;
static llvm::StringLiteral GetCommand() { return "evaluate"; }
void operator()(const llvm::json::Object &request) const override;
FeatureSet GetSupportedFeatures() const override {
return {protocol::eAdapterFeatureEvaluateForHovers};
}
};
class ExceptionInfoRequestHandler : public LegacyRequestHandler {
public:
using LegacyRequestHandler::LegacyRequestHandler;
static llvm::StringLiteral GetCommand() { return "exceptionInfo"; }
FeatureSet GetSupportedFeatures() const override {
return {protocol::eAdapterFeatureExceptionInfoRequest};
}
void operator()(const llvm::json::Object &request) const override;
};
class InitializeRequestHandler
: public RequestHandler<protocol::InitializeRequestArguments,
llvm::Expected<protocol::InitializeResponse>> {
public:
using RequestHandler::RequestHandler;
static llvm::StringLiteral GetCommand() { return "initialize"; }
llvm::Expected<protocol::InitializeResponse>
Run(const protocol::InitializeRequestArguments &args) const override;
};
class LaunchRequestHandler
: public RequestHandler<protocol::LaunchRequestArguments,
protocol::LaunchResponse> {
public:
using RequestHandler::RequestHandler;
static llvm::StringLiteral GetCommand() { return "launch"; }
llvm::Error
Run(const protocol::LaunchRequestArguments &arguments) const override;
void PostRun() const override;
};
class RestartRequestHandler : public LegacyRequestHandler {
public:
using LegacyRequestHandler::LegacyRequestHandler;
static llvm::StringLiteral GetCommand() { return "restart"; }
void operator()(const llvm::json::Object &request) const override;
};
class NextRequestHandler
: public RequestHandler<protocol::NextArguments, protocol::NextResponse> {
public:
using RequestHandler::RequestHandler;
static llvm::StringLiteral GetCommand() { return "next"; }
llvm::Error Run(const protocol::NextArguments &args) const override;
};
class StepInRequestHandler : public RequestHandler<protocol::StepInArguments,
protocol::StepInResponse> {
public:
using RequestHandler::RequestHandler;
static llvm::StringLiteral GetCommand() { return "stepIn"; }
llvm::Error Run(const protocol::StepInArguments &args) const override;
};
class StepInTargetsRequestHandler
: public RequestHandler<
protocol::StepInTargetsArguments,
llvm::Expected<protocol::StepInTargetsResponseBody>> {
public:
using RequestHandler::RequestHandler;
static llvm::StringLiteral GetCommand() { return "stepInTargets"; }
llvm::Expected<protocol::StepInTargetsResponseBody>
Run(const protocol::StepInTargetsArguments &args) const override;
};
class StepOutRequestHandler : public RequestHandler<protocol::StepOutArguments,
protocol::StepOutResponse> {
public:
using RequestHandler::RequestHandler;
static llvm::StringLiteral GetCommand() { return "stepOut"; }
llvm::Error Run(const protocol::StepOutArguments &args) const override;
};
class SetBreakpointsRequestHandler
: public RequestHandler<
protocol::SetBreakpointsArguments,
llvm::Expected<protocol::SetBreakpointsResponseBody>> {
public:
using RequestHandler::RequestHandler;
static llvm::StringLiteral GetCommand() { return "setBreakpoints"; }
FeatureSet GetSupportedFeatures() const override {
return {protocol::eAdapterFeatureConditionalBreakpoints,
protocol::eAdapterFeatureHitConditionalBreakpoints};
}
llvm::Expected<protocol::SetBreakpointsResponseBody>
Run(const protocol::SetBreakpointsArguments &args) const override;
};
class SetExceptionBreakpointsRequestHandler
: public RequestHandler<
protocol::SetExceptionBreakpointsArguments,
llvm::Expected<protocol::SetExceptionBreakpointsResponseBody>> {
public:
using RequestHandler::RequestHandler;
static llvm::StringLiteral GetCommand() { return "setExceptionBreakpoints"; }
FeatureSet GetSupportedFeatures() const override {
/// Prefer the `filterOptions` feature over the `exceptionOptions`.
/// exceptionOptions is not supported in VSCode, while `filterOptions` is
/// supported.
return {protocol::eAdapterFeatureExceptionFilterOptions};
}
llvm::Expected<protocol::SetExceptionBreakpointsResponseBody>
Run(const protocol::SetExceptionBreakpointsArguments &args) const override;
};
class SetFunctionBreakpointsRequestHandler
: public RequestHandler<
protocol::SetFunctionBreakpointsArguments,
llvm::Expected<protocol::SetFunctionBreakpointsResponseBody>> {
public:
using RequestHandler::RequestHandler;
static llvm::StringLiteral GetCommand() { return "setFunctionBreakpoints"; }
FeatureSet GetSupportedFeatures() const override {
return {protocol::eAdapterFeatureFunctionBreakpoints};
}
llvm::Expected<protocol::SetFunctionBreakpointsResponseBody>
Run(const protocol::SetFunctionBreakpointsArguments &args) const override;
};
class DataBreakpointInfoRequestHandler
: public RequestHandler<
protocol::DataBreakpointInfoArguments,
llvm::Expected<protocol::DataBreakpointInfoResponseBody>> {
public:
using RequestHandler::RequestHandler;
static llvm::StringLiteral GetCommand() { return "dataBreakpointInfo"; }
llvm::Expected<protocol::DataBreakpointInfoResponseBody>
Run(const protocol::DataBreakpointInfoArguments &args) const override;
};
class SetDataBreakpointsRequestHandler
: public RequestHandler<
protocol::SetDataBreakpointsArguments,
llvm::Expected<protocol::SetDataBreakpointsResponseBody>> {
public:
using RequestHandler::RequestHandler;
static llvm::StringLiteral GetCommand() { return "setDataBreakpoints"; }
FeatureSet GetSupportedFeatures() const override {
return {protocol::eAdapterFeatureDataBreakpoints};
}
llvm::Expected<protocol::SetDataBreakpointsResponseBody>
Run(const protocol::SetDataBreakpointsArguments &args) const override;
};
class SetInstructionBreakpointsRequestHandler
: public RequestHandler<
protocol::SetInstructionBreakpointsArguments,
llvm::Expected<protocol::SetInstructionBreakpointsResponseBody>> {
public:
using RequestHandler::RequestHandler;
static llvm::StringLiteral GetCommand() {
return "setInstructionBreakpoints";
}
FeatureSet GetSupportedFeatures() const override {
return {protocol::eAdapterFeatureInstructionBreakpoints};
}
llvm::Expected<protocol::SetInstructionBreakpointsResponseBody>
Run(const protocol::SetInstructionBreakpointsArguments &args) const override;
};
class CompileUnitsRequestHandler : public LegacyRequestHandler {
public:
using LegacyRequestHandler::LegacyRequestHandler;
static llvm::StringLiteral GetCommand() { return "compileUnits"; }
void operator()(const llvm::json::Object &request) const override;
};
class ModulesRequestHandler final
: public RequestHandler<std::optional<protocol::ModulesArguments>,
llvm::Expected<protocol::ModulesResponseBody>> {
public:
using RequestHandler::RequestHandler;
static llvm::StringLiteral GetCommand() { return "modules"; }
FeatureSet GetSupportedFeatures() const override {
return {protocol::eAdapterFeatureModulesRequest};
}
llvm::Expected<protocol::ModulesResponseBody>
Run(const std::optional<protocol::ModulesArguments> &args) const override;
};
class PauseRequestHandler : public LegacyRequestHandler {
public:
using LegacyRequestHandler::LegacyRequestHandler;
static llvm::StringLiteral GetCommand() { return "pause"; }
void operator()(const llvm::json::Object &request) const override;
};
class ScopesRequestHandler final
: public RequestHandler<protocol::ScopesArguments,
llvm::Expected<protocol::ScopesResponseBody>> {
public:
using RequestHandler::RequestHandler;
static llvm::StringLiteral GetCommand() { return "scopes"; }
llvm::Expected<protocol::ScopesResponseBody>
Run(const protocol::ScopesArguments &args) const override;
};
class SetVariableRequestHandler final
: public RequestHandler<protocol::SetVariableArguments,
llvm::Expected<protocol::SetVariableResponseBody>> {
public:
using RequestHandler::RequestHandler;
static llvm::StringLiteral GetCommand() { return "setVariable"; }
FeatureSet GetSupportedFeatures() const override {
return {protocol::eAdapterFeatureSetVariable};
}
llvm::Expected<protocol::SetVariableResponseBody>
Run(const protocol::SetVariableArguments &args) const override;
};
class SourceRequestHandler final
: public RequestHandler<protocol::SourceArguments,
llvm::Expected<protocol::SourceResponseBody>> {
public:
using RequestHandler::RequestHandler;
static llvm::StringLiteral GetCommand() { return "source"; }
llvm::Expected<protocol::SourceResponseBody>
Run(const protocol::SourceArguments &args) const override;
};
class StackTraceRequestHandler : public LegacyRequestHandler {
public:
using LegacyRequestHandler::LegacyRequestHandler;
static llvm::StringLiteral GetCommand() { return "stackTrace"; }
void operator()(const llvm::json::Object &request) const override;
FeatureSet GetSupportedFeatures() const override {
return {protocol::eAdapterFeatureDelayedStackTraceLoading};
}
};
class ThreadsRequestHandler
: public RequestHandler<protocol::ThreadsArguments,
llvm::Expected<protocol::ThreadsResponseBody>> {
public:
using RequestHandler::RequestHandler;
static llvm::StringLiteral GetCommand() { return "threads"; }
llvm::Expected<protocol::ThreadsResponseBody>
Run(const protocol::ThreadsArguments &) const override;
};
class VariablesRequestHandler
: public RequestHandler<protocol::VariablesArguments,
llvm::Expected<protocol::VariablesResponseBody>> {
public:
using RequestHandler::RequestHandler;
static llvm::StringLiteral GetCommand() { return "variables"; }
llvm::Expected<protocol::VariablesResponseBody>
Run(const protocol::VariablesArguments &) const override;
};
class LocationsRequestHandler : public LegacyRequestHandler {
public:
using LegacyRequestHandler::LegacyRequestHandler;
static llvm::StringLiteral GetCommand() { return "locations"; }
void operator()(const llvm::json::Object &request) const override;
};
class DisassembleRequestHandler final
: public RequestHandler<protocol::DisassembleArguments,
llvm::Expected<protocol::DisassembleResponseBody>> {
public:
using RequestHandler::RequestHandler;
static llvm::StringLiteral GetCommand() { return "disassemble"; }
FeatureSet GetSupportedFeatures() const override {
return {protocol::eAdapterFeatureDisassembleRequest};
}
llvm::Expected<protocol::DisassembleResponseBody>
Run(const protocol::DisassembleArguments &args) const override;
};
class ReadMemoryRequestHandler final
: public RequestHandler<protocol::ReadMemoryArguments,
llvm::Expected<protocol::ReadMemoryResponseBody>> {
public:
using RequestHandler::RequestHandler;
static llvm::StringLiteral GetCommand() { return "readMemory"; }
FeatureSet GetSupportedFeatures() const override {
return {protocol::eAdapterFeatureReadMemoryRequest};
}
llvm::Expected<protocol::ReadMemoryResponseBody>
Run(const protocol::ReadMemoryArguments &args) const override;
};
class CancelRequestHandler : public RequestHandler<protocol::CancelArguments,
protocol::CancelResponse> {
public:
using RequestHandler::RequestHandler;
static llvm::StringLiteral GetCommand() { return "cancel"; }
FeatureSet GetSupportedFeatures() const override {
return {protocol::eAdapterFeatureCancelRequest};
}
llvm::Error Run(const protocol::CancelArguments &args) const override;
};
class ModuleSymbolsRequestHandler
: public RequestHandler<
protocol::ModuleSymbolsArguments,
llvm::Expected<protocol::ModuleSymbolsResponseBody>> {
public:
using RequestHandler::RequestHandler;
static llvm::StringLiteral GetCommand() { return "__lldb_moduleSymbols"; }
FeatureSet GetSupportedFeatures() const override {
return {protocol::eAdapterFeatureSupportsModuleSymbolsRequest};
}
llvm::Expected<protocol::ModuleSymbolsResponseBody>
Run(const protocol::ModuleSymbolsArguments &args) const override;
};
/// A request used in testing to get the details on all breakpoints that are
/// currently set in the target. This helps us to test "setBreakpoints" and
/// "setFunctionBreakpoints" requests to verify we have the correct set of
/// breakpoints currently set in LLDB.
class TestGetTargetBreakpointsRequestHandler : public LegacyRequestHandler {
public:
using LegacyRequestHandler::LegacyRequestHandler;
static llvm::StringLiteral GetCommand() {
return "_testGetTargetBreakpoints";
}
void operator()(const llvm::json::Object &request) const override;
};
class WriteMemoryRequestHandler final
: public RequestHandler<protocol::WriteMemoryArguments,
llvm::Expected<protocol::WriteMemoryResponseBody>> {
public:
using RequestHandler::RequestHandler;
static llvm::StringLiteral GetCommand() { return "writeMemory"; }
FeatureSet GetSupportedFeatures() const override {
return {protocol::eAdapterFeatureWriteMemoryRequest};
}
llvm::Expected<protocol::WriteMemoryResponseBody>
Run(const protocol::WriteMemoryArguments &args) const override;
};
} // namespace lldb_dap
#endif
|