Skip to content

[lldb-dap] When sending a DAP Output Event break each message into separate lines. #105456

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Aug 21, 2024
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,11 @@ def collect_console(self, timeout_secs, pattern=None):
"console", timeout_secs=timeout_secs, pattern=pattern
)

def collect_stdout(self, timeout_secs, pattern=None):
return self.dap_server.collect_output(
"stdout", timeout_secs=timeout_secs, pattern=pattern
)

def get_local_as_int(self, name, threadId=None):
value = self.dap_server.get_local_variable_value(name, threadId=threadId)
# 'value' may have the variable value and summary.
Expand Down
3 changes: 3 additions & 0 deletions lldb/test/API/tools/lldb-dap/output/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
C_SOURCES := main.c

include Makefile.rules
31 changes: 31 additions & 0 deletions lldb/test/API/tools/lldb-dap/output/TestDAP_output.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
"""
Test lldb-dap output events
"""

from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
import lldbdap_testcase


class TestDAP_output(lldbdap_testcase.DAPTestCaseBase):
def test_output(self):
program = self.getBuildArtifact("a.out")
self.build_and_launch(program)
source = "main.c"
lines = [line_number(source, "// breakpoint 1")]
breakpoint_ids = self.set_source_breakpoints(source, lines)
self.continue_to_breakpoints(breakpoint_ids)

# Ensure partial messages are still sent.
output = self.collect_stdout(timeout_secs=1.0, pattern="abcdef")
self.assertTrue(output and len(output) > 0, "expect no program output")

self.continue_to_exit()

output += self.get_stdout(timeout=lldbdap_testcase.DAPTestCaseBase.timeoutval)
self.assertTrue(output and len(output) > 0, "expect no program output")
self.assertIn(
"abcdefghi\r\nhello world\r\n",
output,
'full output not found in: ' + output,
)
11 changes: 11 additions & 0 deletions lldb/test/API/tools/lldb-dap/output/main.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main() {
printf("abc");
printf("def");
printf("ghi\n");
printf("hello world\n"); // breakpoint 1
return 0;
}
22 changes: 16 additions & 6 deletions lldb/tools/lldb-dap/DAP.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -294,8 +294,6 @@ void DAP::SendOutput(OutputType o, const llvm::StringRef output) {
if (output.empty())
return;

llvm::json::Object event(CreateEventObject("output"));
llvm::json::Object body;
const char *category = nullptr;
switch (o) {
case OutputType::Console:
Expand All @@ -311,10 +309,22 @@ void DAP::SendOutput(OutputType o, const llvm::StringRef output) {
category = "telemetry";
break;
}
body.try_emplace("category", category);
EmplaceSafeString(body, "output", output.str());
event.try_emplace("body", std::move(body));
SendJSON(llvm::json::Value(std::move(event)));

// Send each line of output as an individual event, including the newline if
// present.
::size_t idx = 0;
do {
::size_t end = output.find('\n', idx);
if (end == llvm::StringRef::npos)
end = output.size() - 1;
llvm::json::Object event(CreateEventObject("output"));
llvm::json::Object body;
body.try_emplace("category", category);
EmplaceSafeString(body, "output", output.slice(idx, end + 1).str());
event.try_emplace("body", std::move(body));
SendJSON(llvm::json::Value(std::move(event)));
idx = end + 1;
} while (idx < output.size());
}

// interface ProgressStartEvent extends Event {
Expand Down
2 changes: 1 addition & 1 deletion lldb/tools/lldb-dap/lldb-dap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -399,7 +399,7 @@ void SendProcessEvent(LaunchMethod launch_method) {
// Grab any STDOUT and STDERR from the process and send it up to VS Code
// via an "output" event to the "stdout" and "stderr" categories.
void SendStdOutStdErr(lldb::SBProcess &process) {
char buffer[1024];
char buffer[4096];
size_t count;
while ((count = process.GetSTDOUT(buffer, sizeof(buffer))) > 0)
g_dap.SendOutput(OutputType::Stdout, llvm::StringRef(buffer, count));
Expand Down
Loading