[Lldb-commits] [lldb] a939a9f - [LLDB-DAP] Send Progress update message over DAP (#123837)
via lldb-commits
lldb-commits at lists.llvm.org
Wed Jan 22 15:49:17 PST 2025
Author: Jacob Lalonde
Date: 2025-01-22T15:49:13-08:00
New Revision: a939a9fd53d98f33b94f9121646d5906a2b9f598
URL: https://github.com/llvm/llvm-project/commit/a939a9fd53d98f33b94f9121646d5906a2b9f598
DIFF: https://github.com/llvm/llvm-project/commit/a939a9fd53d98f33b94f9121646d5906a2b9f598.diff
LOG: [LLDB-DAP] Send Progress update message over DAP (#123837)
When testing my SBProgress DAP PR (#123826), I noticed Progress update
messages aren't sent over DAP. This patch adds the lldb progress event's
message to the body when sent over DAP.
Before
![image](https://github.com/user-attachments/assets/404adaa8-b784-4f23-895f-cd3625fdafad)
Now
![image](https://github.com/user-attachments/assets/eb1c3235-0936-4e36-96e5-0a0ee60dabb8)
Tested with my [progress tester
command](https://gist.github.com/Jlalond/48d85e75a91f7a137e3142e6a13d0947),
testing 10 events 5 seconds apart 1-10
Added:
lldb/test/API/tools/lldb-dap/progress/Makefile
lldb/test/API/tools/lldb-dap/progress/Progress_emitter.py
lldb/test/API/tools/lldb-dap/progress/TestDAP_Progress.py
lldb/test/API/tools/lldb-dap/progress/main.cpp
Modified:
lldb/tools/lldb-dap/ProgressEvent.cpp
lldb/tools/lldb-dap/ProgressEvent.h
Removed:
################################################################################
diff --git a/lldb/test/API/tools/lldb-dap/progress/Makefile b/lldb/test/API/tools/lldb-dap/progress/Makefile
new file mode 100644
index 00000000000000..99998b20bcb050
--- /dev/null
+++ b/lldb/test/API/tools/lldb-dap/progress/Makefile
@@ -0,0 +1,3 @@
+CXX_SOURCES := main.cpp
+
+include Makefile.rules
diff --git a/lldb/test/API/tools/lldb-dap/progress/Progress_emitter.py b/lldb/test/API/tools/lldb-dap/progress/Progress_emitter.py
new file mode 100644
index 00000000000000..7f4055cab9ddda
--- /dev/null
+++ b/lldb/test/API/tools/lldb-dap/progress/Progress_emitter.py
@@ -0,0 +1,84 @@
+import inspect
+import optparse
+import shlex
+import sys
+import time
+
+import lldb
+
+
+class ProgressTesterCommand:
+ program = "test-progress"
+
+ @classmethod
+ def register_lldb_command(cls, debugger, module_name):
+ parser = cls.create_options()
+ cls.__doc__ = parser.format_help()
+ # Add any commands contained in this module to LLDB
+ command = "command script add -c %s.%s %s" % (
+ module_name,
+ cls.__name__,
+ cls.program,
+ )
+ debugger.HandleCommand(command)
+ print(
+ 'The "{0}" command has been installed, type "help {0}" or "{0} '
+ '--help" for detailed help.'.format(cls.program)
+ )
+
+ @classmethod
+ def create_options(cls):
+ usage = "usage: %prog [options]"
+ description = "SBProgress testing tool"
+ # Opt parse is deprecated, but leaving this the way it is because it allows help formating
+ # Additionally all our commands use optparse right now, ideally we migrate them all in one go.
+ parser = optparse.OptionParser(
+ description=description, prog=cls.program, usage=usage
+ )
+
+ parser.add_option(
+ "--total", dest="total", help="Total to count up.", type="int"
+ )
+
+ parser.add_option(
+ "--seconds",
+ dest="seconds",
+ help="Total number of seconds to wait between increments",
+ type="int",
+ )
+
+ return parser
+
+ def get_short_help(self):
+ return "Progress Tester"
+
+ def get_long_help(self):
+ return self.help_string
+
+ def __init__(self, debugger, unused):
+ self.parser = self.create_options()
+ self.help_string = self.parser.format_help()
+
+ def __call__(self, debugger, command, exe_ctx, result):
+ command_args = shlex.split(command)
+ try:
+ (cmd_options, args) = self.parser.parse_args(command_args)
+ except:
+ result.SetError("option parsing failed")
+ return
+
+ total = cmd_options.total
+ progress = lldb.SBProgress("Progress tester", "Detail", total, debugger)
+
+ for i in range(1, total):
+ progress.Increment(1, f"Step {i}")
+ time.sleep(cmd_options.seconds)
+
+
+def __lldb_init_module(debugger, dict):
+ # Register all classes that have a register_lldb_command method
+ for _name, cls in inspect.getmembers(sys.modules[__name__]):
+ if inspect.isclass(cls) and callable(
+ getattr(cls, "register_lldb_command", None)
+ ):
+ cls.register_lldb_command(debugger, __name__)
diff --git a/lldb/test/API/tools/lldb-dap/progress/TestDAP_Progress.py b/lldb/test/API/tools/lldb-dap/progress/TestDAP_Progress.py
new file mode 100755
index 00000000000000..36c0cef9c47143
--- /dev/null
+++ b/lldb/test/API/tools/lldb-dap/progress/TestDAP_Progress.py
@@ -0,0 +1,49 @@
+"""
+Test lldb-dap output events
+"""
+
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+import os
+import time
+
+import lldbdap_testcase
+
+
+class TestDAP_progress(lldbdap_testcase.DAPTestCaseBase):
+ @skipIfWindows
+ def test_output(self):
+ program = self.getBuildArtifact("a.out")
+ self.build_and_launch(program)
+ progress_emitter = os.path.join(os.getcwd(), "Progress_emitter.py")
+ print(f"Progress emitter path: {progress_emitter}")
+ source = "main.cpp"
+ # Set breakpoint in the thread function so we can step the threads
+ breakpoint_ids = self.set_source_breakpoints(
+ source, [line_number(source, "// break here")]
+ )
+ self.continue_to_breakpoints(breakpoint_ids)
+ self.dap_server.request_evaluate(
+ f"`command script import {progress_emitter}", context="repl"
+ )
+ self.dap_server.request_evaluate(
+ "`test-progress --total 3 --seconds 1", context="repl"
+ )
+
+ self.dap_server.wait_for_event("progressEnd", 15)
+ # Expect at least a start, an update, and end event
+ # However because the underlying Progress instance is an RAII object and we can't guaruntee
+ # it's deterministic destruction in the python API, we verify just start and update
+ # otherwise this test could be flakey.
+ self.assertTrue(len(self.dap_server.progress_events) > 0)
+ start_found = False
+ update_found = False
+ for event in self.dap_server.progress_events:
+ event_type = event["event"]
+ if "progressStart" in event_type:
+ start_found = True
+ if "progressUpdate" in event_type:
+ update_found = True
+
+ self.assertTrue(start_found)
+ self.assertTrue(update_found)
diff --git a/lldb/test/API/tools/lldb-dap/progress/main.cpp b/lldb/test/API/tools/lldb-dap/progress/main.cpp
new file mode 100644
index 00000000000000..3bac5d0fd6db1a
--- /dev/null
+++ b/lldb/test/API/tools/lldb-dap/progress/main.cpp
@@ -0,0 +1,5 @@
+int main() {
+ char *ptr = "unused";
+ // break here
+ return 0;
+}
diff --git a/lldb/tools/lldb-dap/ProgressEvent.cpp b/lldb/tools/lldb-dap/ProgressEvent.cpp
index 0dcc2ee81001d5..6a4978c055e516 100644
--- a/lldb/tools/lldb-dap/ProgressEvent.cpp
+++ b/lldb/tools/lldb-dap/ProgressEvent.cpp
@@ -117,6 +117,9 @@ json::Value ProgressEvent::ToJSON() const {
body.try_emplace("cancellable", false);
}
+ if (m_event_type == progressUpdate)
+ EmplaceSafeString(body, "message", m_message);
+
std::string timestamp(llvm::formatv("{0:f9}", m_creation_time.count()));
EmplaceSafeString(body, "timestamp", timestamp);
@@ -164,10 +167,10 @@ const ProgressEvent &ProgressEventManager::GetMostRecentEvent() const {
return m_last_update_event ? *m_last_update_event : m_start_event;
}
-void ProgressEventManager::Update(uint64_t progress_id, uint64_t completed,
- uint64_t total) {
+void ProgressEventManager::Update(uint64_t progress_id, llvm::StringRef message,
+ uint64_t completed, uint64_t total) {
if (std::optional<ProgressEvent> event = ProgressEvent::Create(
- progress_id, std::nullopt, completed, total, &GetMostRecentEvent())) {
+ progress_id, message, completed, total, &GetMostRecentEvent())) {
if (event->GetEventType() == progressEnd)
m_finished = true;
@@ -227,7 +230,7 @@ void ProgressEventReporter::Push(uint64_t progress_id, const char *message,
m_unreported_start_events.push(event_manager);
}
} else {
- it->second->Update(progress_id, completed, total);
+ it->second->Update(progress_id, StringRef(message), completed, total);
if (it->second->Finished())
m_event_managers.erase(it);
}
diff --git a/lldb/tools/lldb-dap/ProgressEvent.h b/lldb/tools/lldb-dap/ProgressEvent.h
index 72317b879c803a..d1b9b9dd887cd8 100644
--- a/lldb/tools/lldb-dap/ProgressEvent.h
+++ b/lldb/tools/lldb-dap/ProgressEvent.h
@@ -99,7 +99,8 @@ class ProgressEventManager {
/// Receive a new progress event for the start event and try to report it if
/// appropriate.
- void Update(uint64_t progress_id, uint64_t completed, uint64_t total);
+ void Update(uint64_t progress_id, llvm::StringRef message, uint64_t completed,
+ uint64_t total);
/// \return
/// \b true if a \a progressEnd event has been notified. There's no
More information about the lldb-commits
mailing list