[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