[Lldb-commits] [lldb] fad93cd - Revert "[lldb] [test] Improve stability of llgs vCont-threads tests"
Michał Górny via lldb-commits
lldb-commits at lists.llvm.org
Thu Jul 7 08:01:48 PDT 2022
Author: Michał Górny
Date: 2022-07-07T17:01:43+02:00
New Revision: fad93cd6821992baf0e1b5c45c1606aa5fde2938
URL: https://github.com/llvm/llvm-project/commit/fad93cd6821992baf0e1b5c45c1606aa5fde2938
DIFF: https://github.com/llvm/llvm-project/commit/fad93cd6821992baf0e1b5c45c1606aa5fde2938.diff
LOG: Revert "[lldb] [test] Improve stability of llgs vCont-threads tests"
This reverts commit 86e472317c8fd9309b76c32ca55fcdeaf63f853b.
It breaks Debian buildbot, for some reason.
Added:
lldb/test/API/tools/lldb-server/vCont-threads/TestGdbRemote_vContThreads.py
Modified:
lldb/test/API/tools/lldb-server/vCont-threads/main.cpp
Removed:
lldb/test/API/tools/lldb-server/vCont-threads/TestPartialResume.py
lldb/test/API/tools/lldb-server/vCont-threads/TestSignal.py
################################################################################
diff --git a/lldb/test/API/tools/lldb-server/vCont-threads/TestSignal.py b/lldb/test/API/tools/lldb-server/vCont-threads/TestGdbRemote_vContThreads.py
similarity index 71%
rename from lldb/test/API/tools/lldb-server/vCont-threads/TestSignal.py
rename to lldb/test/API/tools/lldb-server/vCont-threads/TestGdbRemote_vContThreads.py
index 6dde4f9555cf3..606875ed56213 100644
--- a/lldb/test/API/tools/lldb-server/vCont-threads/TestSignal.py
+++ b/lldb/test/API/tools/lldb-server/vCont-threads/TestGdbRemote_vContThreads.py
@@ -1,18 +1,23 @@
+import json
import re
+import time
import gdbremote_testcase
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
from lldbsuite.test import lldbutil
+class TestGdbRemote_vContThreads(gdbremote_testcase.GdbRemoteTestCaseBase):
-class TestSignal(gdbremote_testcase.GdbRemoteTestCaseBase):
def start_threads(self, num):
procs = self.prep_debug_monitor_and_inferior(inferior_args=[str(num)])
+ # start the process and wait for output
self.test_sequence.add_log_lines([
"read packet: $c#63",
- {"direction": "send", "regex": "[$]T.*;reason:signal.*"},
+ {"type": "output_match", "regex": r".*@started\r\n.*"},
], True)
+ # then interrupt it
+ self.add_interrupt_packets()
self.add_threadinfo_collection_packets()
context = self.expect_gdbremote_sequence()
@@ -24,21 +29,22 @@ def start_threads(self, num):
self.reset_test_sequence()
return threads
- SIGNAL_MATCH_RE = re.compile(r"received SIGUSR1 on thread id: ([0-9a-f]+)")
-
def send_and_check_signal(self, vCont_data, threads):
self.test_sequence.add_log_lines([
"read packet: $vCont;{0}#00".format(vCont_data),
- "send packet: $W00#00",
+ {"type": "output_match",
+ "regex": len(threads) *
+ r".*received SIGUSR1 on thread id: ([0-9a-f]+)\r\n.*",
+ "capture": dict((i, "tid{0}".format(i)) for i
+ in range(1, len(threads)+1)),
+ },
], True)
- exp = self.expect_gdbremote_sequence()
- self.reset_test_sequence()
- tids = []
- for line in exp["O_content"].decode().splitlines():
- m = self.SIGNAL_MATCH_RE.match(line)
- if m is not None:
- tids.append(int(m.group(1), 16))
- self.assertEqual(sorted(tids), sorted(threads))
+
+ context = self.expect_gdbremote_sequence()
+ self.assertIsNotNone(context)
+ tids = sorted(int(context["tid{0}".format(x)], 16)
+ for x in range(1, len(threads)+1))
+ self.assertEqual(tids, sorted(threads))
def get_pid(self):
self.add_process_info_collection_packets()
@@ -236,3 +242,72 @@ def test_signal_two_signals(self):
context = self.expect_gdbremote_sequence()
self.assertIsNotNone(context)
+
+ THREAD_MATCH_RE = re.compile(r"thread ([0-9a-f]+) running")
+
+ def continue_and_get_threads_running(self, continue_packet):
+ self.test_sequence.add_log_lines(
+ ["read packet: ${}#00".format(continue_packet),
+ ], True)
+ self.expect_gdbremote_sequence()
+ self.reset_test_sequence()
+ time.sleep(1)
+ self.add_interrupt_packets()
+ exp = self.expect_gdbremote_sequence()
+ found = set()
+ for line in exp["O_content"].decode().splitlines():
+ m = self.THREAD_MATCH_RE.match(line)
+ if m is not None:
+ found.add(int(m.group(1), 16))
+ return found
+
+ @skipIfWindows
+ @add_test_categories(["llgs"])
+ def test_vCont_run_subset_of_threads(self):
+ self.build()
+ self.set_inferior_startup_launch()
+
+ threads = set(self.start_threads(3))
+ all_subthreads = self.continue_and_get_threads_running("c")
+ all_subthreads_list = list(all_subthreads)
+ self.assertEqual(len(all_subthreads), 3)
+ self.assertEqual(threads & all_subthreads, all_subthreads)
+
+ # resume two threads explicitly, stop the third one implicitly
+ self.assertEqual(
+ self.continue_and_get_threads_running(
+ "vCont;c:{:x};c:{:x}".format(*all_subthreads_list[:2])),
+ set(all_subthreads_list[:2]))
+
+ # resume two threads explicitly, stop others explicitly
+ self.assertEqual(
+ self.continue_and_get_threads_running(
+ "vCont;c:{:x};c:{:x};t".format(*all_subthreads_list[:2])),
+ set(all_subthreads_list[:2]))
+
+ # stop one thread explicitly, resume others
+ self.assertEqual(
+ self.continue_and_get_threads_running(
+ "vCont;t:{:x};c".format(all_subthreads_list[-1])),
+ set(all_subthreads_list[:2]))
+
+ # resume one thread explicitly, stop one explicitly,
+ # resume others
+ self.assertEqual(
+ self.continue_and_get_threads_running(
+ "vCont;c:{:x};t:{:x};c".format(*all_subthreads_list[-2:])),
+ set(all_subthreads_list[:2]))
+
+ # resume one thread explicitly, stop one explicitly,
+ # stop others implicitly
+ self.assertEqual(
+ self.continue_and_get_threads_running(
+ "vCont;t:{:x};c:{:x}".format(*all_subthreads_list[:2])),
+ set(all_subthreads_list[1:2]))
+
+ # resume one thread explicitly, stop one explicitly,
+ # stop others explicitly
+ self.assertEqual(
+ self.continue_and_get_threads_running(
+ "vCont;t:{:x};c:{:x};t".format(*all_subthreads_list[:2])),
+ set(all_subthreads_list[1:2]))
diff --git a/lldb/test/API/tools/lldb-server/vCont-threads/TestPartialResume.py b/lldb/test/API/tools/lldb-server/vCont-threads/TestPartialResume.py
deleted file mode 100644
index 2cc60d3d0a5c0..0000000000000
--- a/lldb/test/API/tools/lldb-server/vCont-threads/TestPartialResume.py
+++ /dev/null
@@ -1,128 +0,0 @@
-import re
-
-import gdbremote_testcase
-from lldbsuite.test.decorators import *
-from lldbsuite.test.lldbtest import *
-
-
-class TestPartialResume(gdbremote_testcase.GdbRemoteTestCaseBase):
- THREAD_MATCH_RE = re.compile(r"thread ([0-9a-f]+) running")
-
- def start_vCont_run_subset_of_threads_test(self):
- self.build()
- self.set_inferior_startup_launch()
-
- procs = self.prep_debug_monitor_and_inferior(inferior_args=["3"])
- # grab the main thread id
- self.add_threadinfo_collection_packets()
- main_thread = self.parse_threadinfo_packets(
- self.expect_gdbremote_sequence())
- self.assertEqual(len(main_thread), 1)
- self.reset_test_sequence()
-
- # run until threads start, then grab full thread list
- self.test_sequence.add_log_lines([
- "read packet: $c#63",
- {"direction": "send", "regex": "[$]T.*;reason:signal.*"},
- ], True)
- self.add_threadinfo_collection_packets()
-
- all_threads = self.parse_threadinfo_packets(
- self.expect_gdbremote_sequence())
- self.assertEqual(len(all_threads), 4)
- self.assertIn(main_thread[0], all_threads)
- self.reset_test_sequence()
-
- all_subthreads = set(all_threads) - set(main_thread)
- self.assertEqual(len(all_subthreads), 3)
-
- return (main_thread[0], list(all_subthreads))
-
- def continue_and_get_threads_running(self, main_thread, vCont_req):
- self.test_sequence.add_log_lines(
- ["read packet: $vCont;c:{:x};{}#00".format(main_thread, vCont_req),
- "send packet: $W00#00",
- ], True)
- exp = self.expect_gdbremote_sequence()
- self.reset_test_sequence()
- found = set()
- for line in exp["O_content"].decode().splitlines():
- m = self.THREAD_MATCH_RE.match(line)
- if m is not None:
- found.add(int(m.group(1), 16))
- return found
-
- @skipIfWindows
- @add_test_categories(["llgs"])
- def test_vCont_cxcx(self):
- main_thread, all_subthreads_list = (
- self.start_vCont_run_subset_of_threads_test())
- # resume two threads explicitly, stop the third one implicitly
- self.assertEqual(
- self.continue_and_get_threads_running(
- main_thread,
- "c:{:x};c:{:x}".format(*all_subthreads_list[:2])),
- set(all_subthreads_list[:2]))
-
- @skipIfWindows
- @add_test_categories(["llgs"])
- def test_vCont_cxcxt(self):
- main_thread, all_subthreads_list = (
- self.start_vCont_run_subset_of_threads_test())
- # resume two threads explicitly, stop others explicitly
- self.assertEqual(
- self.continue_and_get_threads_running(
- main_thread,
- "c:{:x};c:{:x};t".format(*all_subthreads_list[:2])),
- set(all_subthreads_list[:2]))
-
- @skipIfWindows
- @add_test_categories(["llgs"])
- def test_vCont_txc(self):
- main_thread, all_subthreads_list = (
- self.start_vCont_run_subset_of_threads_test())
- # stop one thread explicitly, resume others
- self.assertEqual(
- self.continue_and_get_threads_running(
- main_thread,
- "t:{:x};c".format(all_subthreads_list[-1])),
- set(all_subthreads_list[:2]))
-
- @skipIfWindows
- @add_test_categories(["llgs"])
- def test_vCont_cxtxc(self):
- main_thread, all_subthreads_list = (
- self.start_vCont_run_subset_of_threads_test())
- # resume one thread explicitly, stop one explicitly,
- # resume others
- self.assertEqual(
- self.continue_and_get_threads_running(
- main_thread,
- "c:{:x};t:{:x};c".format(*all_subthreads_list[-2:])),
- set(all_subthreads_list[:2]))
-
- @skipIfWindows
- @add_test_categories(["llgs"])
- def test_vCont_txcx(self):
- main_thread, all_subthreads_list = (
- self.start_vCont_run_subset_of_threads_test())
- # resume one thread explicitly, stop one explicitly,
- # stop others implicitly
- self.assertEqual(
- self.continue_and_get_threads_running(
- main_thread,
- "t:{:x};c:{:x}".format(*all_subthreads_list[:2])),
- set(all_subthreads_list[1:2]))
-
- @skipIfWindows
- @add_test_categories(["llgs"])
- def test_vCont_txcxt(self):
- main_thread, all_subthreads_list = (
- self.start_vCont_run_subset_of_threads_test())
- # resume one thread explicitly, stop one explicitly,
- # stop others explicitly
- self.assertEqual(
- self.continue_and_get_threads_running(
- main_thread,
- "t:{:x};c:{:x};t".format(*all_subthreads_list[:2])),
- set(all_subthreads_list[1:2]))
diff --git a/lldb/test/API/tools/lldb-server/vCont-threads/main.cpp b/lldb/test/API/tools/lldb-server/vCont-threads/main.cpp
index c667f003e1d3f..301b54f878dfc 100644
--- a/lldb/test/API/tools/lldb-server/vCont-threads/main.cpp
+++ b/lldb/test/API/tools/lldb-server/vCont-threads/main.cpp
@@ -1,54 +1,31 @@
#include "pseudo_barrier.h"
#include "thread.h"
-#include <atomic>
#include <chrono>
#include <cinttypes>
#include <csignal>
#include <cstdio>
#include <cstdlib>
#include <cstring>
-#include <mutex>
#include <thread>
#include <unistd.h>
#include <vector>
pseudo_barrier_t barrier;
-std::mutex print_mutex;
-std::atomic<bool> can_work = ATOMIC_VAR_INIT(false);
-thread_local volatile sig_atomic_t can_exit_now = false;
static void sigusr1_handler(int signo) {
- std::lock_guard<std::mutex> lock{print_mutex};
- std::printf("received SIGUSR1 on thread id: %" PRIx64 "\n", get_thread_id());
- can_exit_now = true;
+ char buf[100];
+ std::snprintf(buf, sizeof(buf),
+ "received SIGUSR1 on thread id: %" PRIx64 "\n",
+ get_thread_id());
+ write(STDOUT_FILENO, buf, strlen(buf));
}
static void thread_func() {
- // this ensures that all threads start before we SIGSTOP
pseudo_barrier_wait(barrier);
-
- // wait till the main thread indicates that we can go
- // (note: using a mutex here causes hang on FreeBSD when another thread
- // is suspended)
- while (!can_work.load())
- std::this_thread::sleep_for(std::chrono::milliseconds(50));
-
- // the mutex guarantees that two writes don't get interspersed
- {
- std::lock_guard<std::mutex> lock{print_mutex};
+ for (int i = 0; i < 300; ++i) {
std::printf("thread %" PRIx64 " running\n", get_thread_id());
- }
-
- // give other threads a fair chance to run
- for (int i = 0; i < 5; ++i) {
- std::this_thread::yield();
std::this_thread::sleep_for(std::chrono::milliseconds(200));
- if (can_exit_now)
- return;
}
-
- // if we didn't get signaled, terminate the program explicitly.
- _exit(0);
}
int main(int argc, char **argv) {
@@ -59,15 +36,12 @@ int main(int argc, char **argv) {
signal(SIGUSR1, sigusr1_handler);
std::vector<std::thread> threads;
- for (int i = 0; i < num; ++i)
+ for(int i = 0; i < num; ++i)
threads.emplace_back(thread_func);
- // use the barrier to make sure all threads start before we SIGSTOP
pseudo_barrier_wait(barrier);
- std::raise(SIGSTOP);
- // allow the threads to work
- can_work.store(true);
+ std::puts("@started");
for (std::thread &thread : threads)
thread.join();
More information about the lldb-commits
mailing list