[Lldb-commits] [lldb] 3ff6fb6 - [LLDB][SBProgress] Add a finalize method (#128966)
via lldb-commits
lldb-commits at lists.llvm.org
Mon Mar 3 14:01:33 PST 2025
Author: Jacob Lalonde
Date: 2025-03-03T14:01:29-08:00
New Revision: 3ff6fb68d7aadf570a15a8a068ce7b24851e136d
URL: https://github.com/llvm/llvm-project/commit/3ff6fb68d7aadf570a15a8a068ce7b24851e136d
DIFF: https://github.com/llvm/llvm-project/commit/3ff6fb68d7aadf570a15a8a068ce7b24851e136d.diff
LOG: [LLDB][SBProgress] Add a finalize method (#128966)
This patch adds a finalize method which destroys the underlying RAII
SBProgress. My primary motivation for this is so I can write better
tests that are non-flaky, but after discussing with @clayborg in my DAP
message improvement patch (#124648) this is probably an essential API
despite that I originally argued it wasn't.
Added:
Modified:
lldb/bindings/interface/SBProgressDocstrings.i
lldb/include/lldb/API/SBProgress.h
lldb/source/API/SBProgress.cpp
lldb/test/API/python_api/sbprogress/TestSBProgress.py
Removed:
################################################################################
diff --git a/lldb/bindings/interface/SBProgressDocstrings.i b/lldb/bindings/interface/SBProgressDocstrings.i
index 2997fe619fcc7..5459d1af5155c 100644
--- a/lldb/bindings/interface/SBProgressDocstrings.i
+++ b/lldb/bindings/interface/SBProgressDocstrings.i
@@ -12,3 +12,14 @@ and will always send an initial progress update, updates when
Progress::Increment() is called, and also will make sure that a progress
completed update is reported even if the user doesn't explicitly cause one
to be sent.") lldb::SBProgress;
+
+%feature("docstring",
+"Finalize the SBProgress, which will cause a progress end event to be emitted. This
+happens automatically when the SBProcess object is destroyed, but can be done explicitly
+with Finalize to avoid having to rely on the language semantics for destruction.
+
+Note once finalized, no further increments will be processed.") lldb::SBProgress::Finalize;
+
+%feature("docstring",
+"Increment the progress by a given number of units, optionally with a message. Not all progress events are guaraunteed
+to be sent, but incrementing to the total will always guarauntee a progress end event being sent.") lldb::SBProcess::Increment;
diff --git a/lldb/include/lldb/API/SBProgress.h b/lldb/include/lldb/API/SBProgress.h
index d574d1d2982b9..e5e8196bcaa81 100644
--- a/lldb/include/lldb/API/SBProgress.h
+++ b/lldb/include/lldb/API/SBProgress.h
@@ -59,6 +59,11 @@ class LLDB_API SBProgress {
void Increment(uint64_t amount, const char *description = nullptr);
+ /// Explicitly finalize an SBProgress, this can be used to terminate a
+ /// progress on command instead of waiting for a garbage collection or other
+ /// RAII to destroy the contained progress object.
+ void Finalize();
+
protected:
lldb_private::Progress &ref() const;
diff --git a/lldb/source/API/SBProgress.cpp b/lldb/source/API/SBProgress.cpp
index 3e548854ab739..e3318624c5fd1 100644
--- a/lldb/source/API/SBProgress.cpp
+++ b/lldb/source/API/SBProgress.cpp
@@ -40,10 +40,22 @@ SBProgress::~SBProgress() = default;
void SBProgress::Increment(uint64_t amount, const char *description) {
LLDB_INSTRUMENT_VA(amount, description);
+ if (!m_opaque_up)
+ return;
+
std::optional<std::string> description_opt;
if (description && description[0])
description_opt = description;
m_opaque_up->Increment(amount, std::move(description_opt));
}
+void SBProgress::Finalize() {
+ // The lldb_private::Progress object is designed to be RAII and send the end
+ // progress event when it gets destroyed. So force our contained object to be
+ // destroyed and send the progress end event. Clearing this object also allows
+ // all other methods to quickly return without doing any work if they are
+ // called after this method.
+ m_opaque_up.reset();
+}
+
lldb_private::Progress &SBProgress::ref() const { return *m_opaque_up; }
diff --git a/lldb/test/API/python_api/sbprogress/TestSBProgress.py b/lldb/test/API/python_api/sbprogress/TestSBProgress.py
index 1b8f01d3e8bb1..2a0689a52a185 100644
--- a/lldb/test/API/python_api/sbprogress/TestSBProgress.py
+++ b/lldb/test/API/python_api/sbprogress/TestSBProgress.py
@@ -5,35 +5,6 @@
class SBProgressTestCase(TestBase):
- def test_with_external_bit_set(self):
- """Test SBProgress events are listened to when the external bit is set."""
-
- progress = lldb.SBProgress("Test SBProgress", "Test progress", self.dbg)
- listener = lldb.SBListener("Test listener")
- broadcaster = self.dbg.GetBroadcaster()
- broadcaster.AddListener(listener, lldb.eBroadcastBitExternalProgress)
- event = lldb.SBEvent()
-
- expected_string = "Test progress first increment"
- progress.Increment(1, expected_string)
- self.assertTrue(listener.PeekAtNextEvent(event))
- stream = lldb.SBStream()
- event.GetDescription(stream)
- self.assertIn(expected_string, stream.GetData())
-
- def test_without_external_bit_set(self):
- """Test SBProgress events are not listened to on the internal progress bit."""
-
- progress = lldb.SBProgress("Test SBProgress", "Test progress", self.dbg)
- listener = lldb.SBListener("Test listener")
- broadcaster = self.dbg.GetBroadcaster()
- broadcaster.AddListener(listener, lldb.eBroadcastBitProgress)
- event = lldb.SBEvent()
-
- expected_string = "Test progress first increment"
- progress.Increment(1, expected_string)
- self.assertFalse(listener.PeekAtNextEvent(event))
-
def test_with_external_bit_set(self):
"""Test SBProgress can handle null events."""
@@ -65,3 +36,33 @@ def test_with_external_bit_set(self):
stream = lldb.SBStream()
event.GetDescription(stream)
self.assertIn("Step 3", stream.GetData())
+
+ def test_progress_finalize_non_deterministic_progress(self):
+ """Test SBProgress finalize sends the progressEnd event"""
+
+ progress = lldb.SBProgress("Test SBProgress", "Test finalize", self.dbg)
+ listener = lldb.SBListener("Test listener")
+ broadcaster = self.dbg.GetBroadcaster()
+ broadcaster.AddListener(listener, lldb.eBroadcastBitExternalProgressCategory)
+ event = lldb.SBEvent()
+ progress.Finalize()
+ self.assertTrue(listener.WaitForEvent(5, event))
+ stream = lldb.SBStream()
+ event.GetDescription(stream)
+ self.assertIn("type = end", stream.GetData())
+
+ def test_progress_finalize_deterministic_progress(self):
+ """Test SBProgress finalize sends the progressEnd event"""
+
+ progress = lldb.SBProgress("Test SBProgress", "Test finalize", 13, self.dbg)
+ listener = lldb.SBListener("Test listener")
+ broadcaster = self.dbg.GetBroadcaster()
+ broadcaster.AddListener(listener, lldb.eBroadcastBitExternalProgressCategory)
+ event = lldb.SBEvent()
+ progress.Finalize()
+ self.assertTrue(listener.WaitForEvent(5, event))
+ stream = lldb.SBStream()
+ event.GetDescription(stream)
+ # Note even for progresses with a total, the total isn't
+ # sent in the end message.
+ self.assertIn("type = end", stream.GetData())
More information about the lldb-commits
mailing list