[Lldb-commits] [lldb] [lldb] Fix flaky TestConcurrentTwoWatchpointsOneSignal (PR #221697)
Charles Zablit via lldb-commits
lldb-commits at lists.llvm.org
Mon Sep 7 07:11:09 PDT 2026
https://github.com/charles-zablit updated https://github.com/llvm/llvm-project/pull/221697
>From 347f84e86e0b63da16669cfcf7d9a49df367b55f Mon Sep 17 00:00:00 2001
From: Charles Zablit <c_zablit at apple.com>
Date: Mon, 7 Sep 2026 12:36:49 +0200
Subject: [PATCH 1/4] [lldb] Isolate g_watchme in memory to fix flaky
TestConcurrentTwoWatchpointsOneSignal
---
.../API/functionalities/thread/concurrent_events/main.cpp | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/lldb/test/API/functionalities/thread/concurrent_events/main.cpp b/lldb/test/API/functionalities/thread/concurrent_events/main.cpp
index 84d8c7015a796..ba4ab62d3fca9 100644
--- a/lldb/test/API/functionalities/thread/concurrent_events/main.cpp
+++ b/lldb/test/API/functionalities/thread/concurrent_events/main.cpp
@@ -19,7 +19,9 @@ typedef std::vector<pthread_t> thread_vector;
pseudo_barrier_t g_barrier;
int g_breakpoint = 0;
int g_sigusr1_count = 0;
-uint32_t g_watchme;
+
+alignas(16) uint32_t g_watchme;
+uint32_t g_watchme_padding[4];
struct action_args {
int delay;
>From 6b462a57434428656f044640030abbc2b2291186 Mon Sep 17 00:00:00 2001
From: Charles Zablit <c_zablit at apple.com>
Date: Mon, 7 Sep 2026 15:12:52 +0200
Subject: [PATCH 2/4] fixup! [lldb] Isolate g_watchme in memory to fix flaky
TestConcurrentTwoWatchpointsOneSignal
---
.../Python/lldbsuite/test/concurrent_base.py | 2 +-
.../thread/concurrent_events/main.cpp | 16 ++++++++++++----
2 files changed, 13 insertions(+), 5 deletions(-)
diff --git a/lldb/packages/Python/lldbsuite/test/concurrent_base.py b/lldb/packages/Python/lldbsuite/test/concurrent_base.py
index a45b4207a834b..adb5c1d0dce88 100644
--- a/lldb/packages/Python/lldbsuite/test/concurrent_base.py
+++ b/lldb/packages/Python/lldbsuite/test/concurrent_base.py
@@ -171,7 +171,7 @@ def do_thread_actions(
# only report this as 1 hit for all threads, because they all wrote
# the same value. The testsuite needs "write" style watchpoints to
# get the correct number of hits reported.
- self.runCmd("watchpoint set variable -w write g_watchme")
+ self.runCmd("watchpoint set variable -w write g_watchme.data")
for w in self.inferior_target.watchpoint_iter():
self.thread_watchpoint = w
self.assertTrue(
diff --git a/lldb/test/API/functionalities/thread/concurrent_events/main.cpp b/lldb/test/API/functionalities/thread/concurrent_events/main.cpp
index ba4ab62d3fca9..9fcc6769bf2f1 100644
--- a/lldb/test/API/functionalities/thread/concurrent_events/main.cpp
+++ b/lldb/test/API/functionalities/thread/concurrent_events/main.cpp
@@ -20,8 +20,16 @@ pseudo_barrier_t g_barrier;
int g_breakpoint = 0;
int g_sigusr1_count = 0;
-alignas(16) uint32_t g_watchme;
-uint32_t g_watchme_padding[4];
+// Hardware watchpoints round the watched address/size to an alignment
+// boundary, so a watchpoint on a plain global could end up covering a
+// neighboring global too. Group the watched data with trailing padding in a
+// single aligned struct so the compiler is guaranteed to lay them out
+// together and nothing else can share the watchpoint's range.
+#define WATCHPOINT_SIZE 16
+struct alignas(WATCHPOINT_SIZE) WatchMePadding {
+ uint32_t data;
+ char padding_after[WATCHPOINT_SIZE];
+} g_watchme;
struct action_args {
int delay;
@@ -66,7 +74,7 @@ watchpoint_func (void *input) {
pseudo_barrier_wait(g_barrier);
do_action_args(input);
- g_watchme = 1; // watchpoint triggers here
+ g_watchme.data = 1; // watchpoint triggers here
return 0;
}
@@ -114,7 +122,7 @@ void start_threads(thread_vector& threads,
int dotest()
{
- g_watchme = 0;
+ g_watchme.data = 0;
// Actions are triggered immediately after the thread is spawned
unsigned num_breakpoint_threads = 1;
>From 6954df3e86f0aac57d60a5319199239b3985f52c Mon Sep 17 00:00:00 2001
From: Charles Zablit <c_zablit at apple.com>
Date: Mon, 7 Sep 2026 15:16:54 +0200
Subject: [PATCH 3/4] fix formatting
---
.../thread/concurrent_events/main.cpp | 115 +++++++++---------
1 file changed, 59 insertions(+), 56 deletions(-)
diff --git a/lldb/test/API/functionalities/thread/concurrent_events/main.cpp b/lldb/test/API/functionalities/thread/concurrent_events/main.cpp
index 9fcc6769bf2f1..445c0cd9af2ce 100644
--- a/lldb/test/API/functionalities/thread/concurrent_events/main.cpp
+++ b/lldb/test/API/functionalities/thread/concurrent_events/main.cpp
@@ -74,7 +74,7 @@ watchpoint_func (void *input) {
pseudo_barrier_wait(g_barrier);
do_action_args(input);
- g_watchme.data = 1; // watchpoint triggers here
+ g_watchme.data = 1; // watchpoint triggers here
return 0;
}
@@ -122,61 +122,64 @@ void start_threads(thread_vector& threads,
int dotest()
{
- g_watchme.data = 0;
-
- // Actions are triggered immediately after the thread is spawned
- unsigned num_breakpoint_threads = 1;
- unsigned num_watchpoint_threads = 0;
- unsigned num_signal_threads = 1;
- unsigned num_crash_threads = 0;
-
- // Actions below are triggered after a 1-second delay
- unsigned num_delay_breakpoint_threads = 0;
- unsigned num_delay_watchpoint_threads = 0;
- unsigned num_delay_signal_threads = 0;
- unsigned num_delay_crash_threads = 0;
-
- register_signal_handler(SIGUSR1, sigusr1_handler); // Break here and adjust num_[breakpoint|watchpoint|signal|crash]_threads
-
- unsigned total_threads = num_breakpoint_threads \
- + num_watchpoint_threads \
- + num_signal_threads \
- + num_crash_threads \
- + num_delay_breakpoint_threads \
- + num_delay_watchpoint_threads \
- + num_delay_signal_threads \
- + num_delay_crash_threads;
-
- // Don't let either thread do anything until they're both ready.
- pseudo_barrier_init(g_barrier, total_threads);
-
- action_counts actions;
- actions.push_back(std::make_pair(num_breakpoint_threads, breakpoint_func));
- actions.push_back(std::make_pair(num_watchpoint_threads, watchpoint_func));
- actions.push_back(std::make_pair(num_signal_threads, signal_func));
- actions.push_back(std::make_pair(num_crash_threads, crash_func));
-
- action_counts delay_actions;
- delay_actions.push_back(std::make_pair(num_delay_breakpoint_threads, breakpoint_func));
- delay_actions.push_back(std::make_pair(num_delay_watchpoint_threads, watchpoint_func));
- delay_actions.push_back(std::make_pair(num_delay_signal_threads, signal_func));
- delay_actions.push_back(std::make_pair(num_delay_crash_threads, crash_func));
-
- // Create threads that handle instant actions
- thread_vector threads;
- start_threads(threads, actions);
-
- // Create threads that handle delayed actions
- action_args delay_arg;
- delay_arg.delay = 1;
- start_threads(threads, delay_actions, &delay_arg);
-
- // Join all threads
- typedef std::vector<pthread_t>::iterator thread_iterator;
- for(thread_iterator t = threads.begin(); t != threads.end(); ++t)
- pthread_join(*t, 0);
-
- return 0;
+ g_watchme.data = 0;
+
+ // Actions are triggered immediately after the thread is spawned
+ unsigned num_breakpoint_threads = 1;
+ unsigned num_watchpoint_threads = 0;
+ unsigned num_signal_threads = 1;
+ unsigned num_crash_threads = 0;
+
+ // Actions below are triggered after a 1-second delay
+ unsigned num_delay_breakpoint_threads = 0;
+ unsigned num_delay_watchpoint_threads = 0;
+ unsigned num_delay_signal_threads = 0;
+ unsigned num_delay_crash_threads = 0;
+
+ register_signal_handler(
+ SIGUSR1,
+ sigusr1_handler); // Break here and adjust
+ // num_[breakpoint|watchpoint|signal|crash]_threads
+
+ unsigned total_threads = num_breakpoint_threads + num_watchpoint_threads +
+ num_signal_threads + num_crash_threads +
+ num_delay_breakpoint_threads +
+ num_delay_watchpoint_threads +
+ num_delay_signal_threads + num_delay_crash_threads;
+
+ // Don't let either thread do anything until they're both ready.
+ pseudo_barrier_init(g_barrier, total_threads);
+
+ action_counts actions;
+ actions.push_back(std::make_pair(num_breakpoint_threads, breakpoint_func));
+ actions.push_back(std::make_pair(num_watchpoint_threads, watchpoint_func));
+ actions.push_back(std::make_pair(num_signal_threads, signal_func));
+ actions.push_back(std::make_pair(num_crash_threads, crash_func));
+
+ action_counts delay_actions;
+ delay_actions.push_back(
+ std::make_pair(num_delay_breakpoint_threads, breakpoint_func));
+ delay_actions.push_back(
+ std::make_pair(num_delay_watchpoint_threads, watchpoint_func));
+ delay_actions.push_back(
+ std::make_pair(num_delay_signal_threads, signal_func));
+ delay_actions.push_back(std::make_pair(num_delay_crash_threads, crash_func));
+
+ // Create threads that handle instant actions
+ thread_vector threads;
+ start_threads(threads, actions);
+
+ // Create threads that handle delayed actions
+ action_args delay_arg;
+ delay_arg.delay = 1;
+ start_threads(threads, delay_actions, &delay_arg);
+
+ // Join all threads
+ typedef std::vector<pthread_t>::iterator thread_iterator;
+ for (thread_iterator t = threads.begin(); t != threads.end(); ++t)
+ pthread_join(*t, 0);
+
+ return 0;
}
int main ()
>From 62f353c72f2ad00d661a0d64713d4fcf28205ac5 Mon Sep 17 00:00:00 2001
From: Charles Zablit <c_zablit at apple.com>
Date: Mon, 7 Sep 2026 16:10:51 +0200
Subject: [PATCH 4/4] fix tests
---
.../API/functionalities/thread/concurrent_events/main.cpp | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)
diff --git a/lldb/test/API/functionalities/thread/concurrent_events/main.cpp b/lldb/test/API/functionalities/thread/concurrent_events/main.cpp
index 445c0cd9af2ce..ee7eae108e3ca 100644
--- a/lldb/test/API/functionalities/thread/concurrent_events/main.cpp
+++ b/lldb/test/API/functionalities/thread/concurrent_events/main.cpp
@@ -136,10 +136,9 @@ int dotest()
unsigned num_delay_signal_threads = 0;
unsigned num_delay_crash_threads = 0;
- register_signal_handler(
- SIGUSR1,
- sigusr1_handler); // Break here and adjust
- // num_[breakpoint|watchpoint|signal|crash]_threads
+ // clang-format off
+ register_signal_handler(SIGUSR1, sigusr1_handler); // Break here and adjust num_[breakpoint|watchpoint|signal|crash]_threads
+ // clang-format on
unsigned total_threads = num_breakpoint_threads + num_watchpoint_threads +
num_signal_threads + num_crash_threads +
More information about the lldb-commits
mailing list