Skip to content

Commit 61f5407

Browse files
committed
[lldb-dap] Creating an API for sending custom dap events from lldb-dap.
Custom DAP events can be detected using https://code.visualstudio.com/api/references/vscode-api#debug.onDidReceiveDebugSessionCustomEvent. This API allows an lldb python script to send custom events to the DAP client to allow extensions to handle these custom events.
1 parent 224f62d commit 61f5407

File tree

8 files changed

+125
-1
lines changed

8 files changed

+125
-1
lines changed

lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1267,7 +1267,7 @@ def run_vscode(dbg, args, options):
12671267
def main():
12681268
parser = optparse.OptionParser(
12691269
description=(
1270-
"A testing framework for the Visual Studio Code Debug " "Adaptor protocol"
1270+
"A testing framework for the Visual Studio Code Debug Adaptor protocol"
12711271
)
12721272
)
12731273

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
C_SOURCES := main.c
2+
3+
include Makefile.rules
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
"""
2+
Test lldb-dap custom-event integration.
3+
"""
4+
5+
import json
6+
7+
from lldbsuite.test.decorators import *
8+
from lldbsuite.test.lldbtest import *
9+
import lldbdap_testcase
10+
11+
12+
class TestDAP_customEvent(lldbdap_testcase.DAPTestCaseBase):
13+
def test_custom_event(self):
14+
"""
15+
Test sending a custom event.
16+
"""
17+
program = self.getBuildArtifact("a.out")
18+
source = "main.c"
19+
custom_event_body = {
20+
"key": 321,
21+
"arr": [True],
22+
}
23+
self.build_and_launch(
24+
program,
25+
stopCommands=[
26+
"lldb-dap custom-event my-custom-event-no-body",
27+
"lldb-dap custom-event my-custom-event '{}'".format(
28+
json.dumps(custom_event_body)
29+
),
30+
],
31+
)
32+
33+
breakpoint_line = line_number(source, "// breakpoint")
34+
35+
self.set_source_breakpoints(source, [breakpoint_line])
36+
self.continue_to_next_stop()
37+
38+
custom_event = self.dap_server.wait_for_event(
39+
filter=["my-custom-event-no-body"]
40+
)
41+
self.assertEquals(custom_event["event"], "my-custom-event-no-body")
42+
self.assertIsNone(custom_event.get("body", None))
43+
44+
custom_event = self.dap_server.wait_for_event(filter=["my-custom-event"])
45+
self.assertEquals(custom_event["event"], "my-custom-event")
46+
self.assertEquals(custom_event["body"], custom_event_body)
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
#include <stdio.h>
2+
3+
int main(int argc, char const *argv[]) {
4+
printf("example\n"); // breakpoint 1
5+
return 0;
6+
}

lldb/tools/lldb-dap/DAP.cpp

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -962,6 +962,44 @@ bool ReplModeRequestHandler::DoExecute(lldb::SBDebugger debugger,
962962
return true;
963963
}
964964

965+
// Sends a custom DAP event with an optional body.
966+
//
967+
// See
968+
// https://code.visualstudio.com/api/references/vscode-api#debug.onDidReceiveDebugSessionCustomEvent
969+
bool CustomDAPEventRequestHandler::DoExecute(
970+
lldb::SBDebugger debugger, char **command,
971+
lldb::SBCommandReturnObject &result) {
972+
// Command format like: `custom-event <name> <body>?`
973+
if (!command || !command[0] || llvm::StringRef(command[0]).empty()) {
974+
result.SetError("Invalid use of custom-event, expected format "
975+
"`custom-event <name> <body>?`.");
976+
return false;
977+
}
978+
979+
llvm::StringRef name{command[0]};
980+
llvm::json::Object event(CreateEventObject(name));
981+
982+
if (command[1] && !llvm::StringRef(command[1]).empty()) {
983+
llvm::StringRef raw_body{command[1]};
984+
985+
llvm::Expected<llvm::json::Value> body = llvm::json::parse(raw_body);
986+
987+
if (!body) {
988+
llvm::Error err = body.takeError();
989+
std::string msg = "Failed to parse custom event body: " +
990+
llvm::toString(std::move(err));
991+
result.SetError(msg.c_str());
992+
return false;
993+
}
994+
995+
event.try_emplace("body", std::move(*body));
996+
}
997+
998+
g_dap.SendJSON(llvm::json::Value(std::move(event)));
999+
result.SetStatus(lldb::eReturnStatusSuccessFinishNoResult);
1000+
return true;
1001+
}
1002+
9651003
void DAP::SetFrameFormat(llvm::StringRef format) {
9661004
if (format.empty())
9671005
return;

lldb/tools/lldb-dap/DAP.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,11 @@ struct ReplModeRequestHandler : public lldb::SBCommandPluginInterface {
144144
lldb::SBCommandReturnObject &result) override;
145145
};
146146

147+
struct CustomDAPEventRequestHandler : public lldb::SBCommandPluginInterface {
148+
bool DoExecute(lldb::SBDebugger debugger, char **command,
149+
lldb::SBCommandReturnObject &result) override;
150+
};
151+
147152
struct DAP {
148153
std::string debug_adaptor_path;
149154
InputStream input;

lldb/tools/lldb-dap/README.md

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -290,6 +290,30 @@ The initial repl-mode can be configured with the cli flag `--repl-mode=<mode>`
290290
and may also be adjusted at runtime using the lldb command
291291
`lldb-dap repl-mode <mode>`.
292292

293+
#### `lldb-dap custom-event`
294+
295+
lldb-dap includes a custom command to trigger a Debug Adapter Protocol event
296+
from a script. [See the specification](https://microsoft.github.io/debug-adapter-protocol/specification#Base_Protocol_Event)
297+
for more details on Debug Adapter Protocol events.
298+
299+
This command has the format:
300+
301+
```
302+
lldb-dap custom-event <name> <body>?
303+
```
304+
305+
For example you can use a launch configuration hook to run the command like:
306+
307+
```json
308+
{
309+
"program": "exe",
310+
"stopCommands": [
311+
"lldb-dap custom-event MyStopEvent",
312+
"lldb-dap custom-event MyStopEvent '{\"key\":321}",
313+
]
314+
}
315+
```
316+
293317
## Contributing
294318

295319
`lldb-dap` and `lldb` are developed under the umbrella of the [LLVM project](https://llvm.org/).

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1896,6 +1896,8 @@ void request_initialize(const llvm::json::Object &request) {
18961896
cmd.AddCommand(
18971897
"repl-mode", new ReplModeRequestHandler(),
18981898
"Get or set the repl behavior of lldb-dap evaluation requests.");
1899+
cmd.AddCommand("custom-event", new CustomDAPEventRequestHandler(),
1900+
"Fires a custom lldb-dap event.");
18991901

19001902
g_dap.progress_event_thread = std::thread(ProgressEventThreadFunction);
19011903

0 commit comments

Comments
 (0)