Skip to content

Commit 6ba704a

Browse files
authored
[lldb-dap] Migrate 'stepIn' request to well structured types. (#137071)
Migrates the 'stepIn' request handler to have well structured types instead of raw json values. I also noticed in the 'next' request handler we were not passing the 'RunMode' flag. Updated the 'next' request handler as well.
1 parent 93705c3 commit 6ba704a

File tree

5 files changed

+72
-80
lines changed

5 files changed

+72
-80
lines changed

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include "llvm/Support/Error.h"
1414

1515
using namespace llvm;
16+
using namespace lldb;
1617
using namespace lldb_dap::protocol;
1718

1819
namespace lldb_dap {
@@ -35,7 +36,7 @@ Error NextRequestHandler::Run(const NextArguments &args) const {
3536
if (args.granularity == eSteppingGranularityInstruction) {
3637
thread.StepInstruction(/*step_over=*/true);
3738
} else {
38-
thread.StepOver();
39+
thread.StepOver(args.singleThread ? eOnlyThisThread : eOnlyDuringStepping);
3940
}
4041

4142
return Error::success();

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

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -298,11 +298,12 @@ class NextRequestHandler
298298
llvm::Error Run(const protocol::NextArguments &args) const override;
299299
};
300300

301-
class StepInRequestHandler : public LegacyRequestHandler {
301+
class StepInRequestHandler : public RequestHandler<protocol::StepInArguments,
302+
protocol::StepInResponse> {
302303
public:
303-
using LegacyRequestHandler::LegacyRequestHandler;
304+
using RequestHandler::RequestHandler;
304305
static llvm::StringLiteral GetCommand() { return "stepIn"; }
305-
void operator()(const llvm::json::Object &request) const override;
306+
llvm::Error Run(const protocol::StepInArguments &args) const override;
306307
};
307308

308309
class StepInTargetsRequestHandler : public LegacyRequestHandler {

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

Lines changed: 35 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -8,91 +8,50 @@
88

99
#include "DAP.h"
1010
#include "EventHelper.h"
11-
#include "JSONUtils.h"
11+
#include "Protocol/ProtocolRequests.h"
12+
#include "Protocol/ProtocolTypes.h"
1213
#include "RequestHandler.h"
1314

15+
using namespace llvm;
16+
using namespace lldb;
17+
using namespace lldb_dap::protocol;
18+
1419
namespace lldb_dap {
1520

16-
// "StepInRequest": {
17-
// "allOf": [ { "$ref": "#/definitions/Request" }, {
18-
// "type": "object",
19-
// "description": "StepIn request; value of command field is 'stepIn'. The
20-
// request starts the debuggee to step into a function/method if possible.
21-
// If it cannot step into a target, 'stepIn' behaves like 'next'. The debug
22-
// adapter first sends the StepInResponse and then a StoppedEvent (event
23-
// type 'step') after the step has completed. If there are multiple
24-
// function/method calls (or other targets) on the source line, the optional
25-
// argument 'targetId' can be used to control into which target the 'stepIn'
26-
// should occur. The list of possible targets for a given source line can be
27-
// retrieved via the 'stepInTargets' request.", "properties": {
28-
// "command": {
29-
// "type": "string",
30-
// "enum": [ "stepIn" ]
31-
// },
32-
// "arguments": {
33-
// "$ref": "#/definitions/StepInArguments"
34-
// }
35-
// },
36-
// "required": [ "command", "arguments" ]
37-
// }]
38-
// },
39-
// "StepInArguments": {
40-
// "type": "object",
41-
// "description": "Arguments for 'stepIn' request.",
42-
// "properties": {
43-
// "threadId": {
44-
// "type": "integer",
45-
// "description": "Execute 'stepIn' for this thread."
46-
// },
47-
// "targetId": {
48-
// "type": "integer",
49-
// "description": "Optional id of the target to step into."
50-
// },
51-
// "granularity": {
52-
// "$ref": "#/definitions/SteppingGranularity",
53-
// "description": "Stepping granularity. If no granularity is specified, a
54-
// granularity of `statement` is assumed."
55-
// }
56-
// },
57-
// "required": [ "threadId" ]
58-
// },
59-
// "StepInResponse": {
60-
// "allOf": [ { "$ref": "#/definitions/Response" }, {
61-
// "type": "object",
62-
// "description": "Response to 'stepIn' request. This is just an
63-
// acknowledgement, so no body field is required."
64-
// }]
65-
// }
66-
void StepInRequestHandler::operator()(const llvm::json::Object &request) const {
67-
llvm::json::Object response;
68-
FillResponse(request, response);
69-
const auto *arguments = request.getObject("arguments");
21+
// The request resumes the given thread to step into a function/method and
22+
// allows all other threads to run freely by resuming them. If the debug adapter
23+
// supports single thread execution (see capability
24+
// `supportsSingleThreadExecutionRequests`), setting the `singleThread` argument
25+
// to true prevents other suspended threads from resuming. If the request cannot
26+
// step into a target, `stepIn` behaves like the `next` request. The debug
27+
// adapter first sends the response and then a `stopped` event (with reason
28+
// `step`) after the step has completed. If there are multiple function/method
29+
// calls (or other targets) on the source line, the argument `targetId` can be
30+
// used to control into which target the `stepIn` should occur. The list of
31+
// possible targets for a given source line can be retrieved via the
32+
// `stepInTargets` request.
33+
Error StepInRequestHandler::Run(const StepInArguments &args) const {
34+
SBThread thread = dap.GetLLDBThread(args.threadId);
35+
if (!thread.IsValid())
36+
return make_error<DAPError>("invalid thread");
37+
38+
// Remember the thread ID that caused the resume so we can set the
39+
// "threadCausedFocus" boolean value in the "stopped" events.
40+
dap.focus_tid = thread.GetThreadID();
41+
42+
if (args.granularity == eSteppingGranularityInstruction) {
43+
thread.StepInstruction(/*step_over=*/false);
44+
return Error::success();
45+
}
7046

7147
std::string step_in_target;
72-
const auto target_id =
73-
GetInteger<uint64_t>(arguments, "targetId").value_or(0);
74-
auto it = dap.step_in_targets.find(target_id);
48+
auto it = dap.step_in_targets.find(args.targetId.value_or(0));
7549
if (it != dap.step_in_targets.end())
7650
step_in_target = it->second;
7751

78-
const bool single_thread =
79-
GetBoolean(arguments, "singleThread").value_or(false);
80-
lldb::RunMode run_mode =
81-
single_thread ? lldb::eOnlyThisThread : lldb::eOnlyDuringStepping;
82-
lldb::SBThread thread = dap.GetLLDBThread(*arguments);
83-
if (thread.IsValid()) {
84-
// Remember the thread ID that caused the resume so we can set the
85-
// "threadCausedFocus" boolean value in the "stopped" events.
86-
dap.focus_tid = thread.GetThreadID();
87-
if (HasInstructionGranularity(*arguments)) {
88-
thread.StepInstruction(/*step_over=*/false);
89-
} else {
90-
thread.StepInto(step_in_target.c_str(), run_mode);
91-
}
92-
} else {
93-
response["success"] = llvm::json::Value(false);
94-
}
95-
dap.SendJSON(llvm::json::Value(std::move(response)));
52+
RunMode run_mode = args.singleThread ? eOnlyThisThread : eOnlyDuringStepping;
53+
thread.StepInto(step_in_target.c_str(), run_mode);
54+
return Error::success();
9655
}
9756

9857
} // namespace lldb_dap

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

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,4 +121,13 @@ bool fromJSON(const llvm::json::Value &Params, NextArguments &NA,
121121
OM.mapOptional("granularity", NA.granularity);
122122
}
123123

124+
bool fromJSON(const llvm::json::Value &Params, StepInArguments &SIA,
125+
llvm::json::Path P) {
126+
json::ObjectMapper OM(Params, P);
127+
return OM && OM.map("threadId", SIA.threadId) &&
128+
OM.map("targetId", SIA.targetId) &&
129+
OM.mapOptional("singleThread", SIA.singleThread) &&
130+
OM.mapOptional("granularity", SIA.granularity);
131+
}
132+
124133
} // namespace lldb_dap::protocol

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

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,28 @@ bool fromJSON(const llvm::json::Value &, NextArguments &, llvm::json::Path);
256256
/// body field is required.
257257
using NextResponse = VoidResponse;
258258

259+
/// Arguments for `stepIn` request.
260+
struct StepInArguments {
261+
/// Specifies the thread for which to resume execution for one step-into (of
262+
/// the given granularity).
263+
uint64_t threadId = LLDB_INVALID_THREAD_ID;
264+
265+
/// If this flag is true, all other suspended threads are not resumed.
266+
bool singleThread = false;
267+
268+
/// Id of the target to step into.
269+
std::optional<uint64_t> targetId;
270+
271+
/// Stepping granularity. If no granularity is specified, a granularity of
272+
/// `statement` is assumed.
273+
SteppingGranularity granularity = eSteppingGranularityStatement;
274+
};
275+
bool fromJSON(const llvm::json::Value &, StepInArguments &, llvm::json::Path);
276+
277+
/// Response to `stepIn` request. This is just an acknowledgement, so no
278+
/// body field is required.
279+
using StepInResponse = VoidResponse;
280+
259281
} // namespace lldb_dap::protocol
260282

261283
#endif

0 commit comments

Comments
 (0)