[Lldb-commits] [lldb] 04b766d - [lldb/test] Deflake TestGdbRemote_vContThreads even more

Pavel Labath via lldb-commits lldb-commits at lists.llvm.org
Tue Mar 30 08:03:33 PDT 2021


Author: Pavel Labath
Date: 2021-03-30T17:03:14+02:00
New Revision: 04b766dab0d9d786ab5695336348b0c01646cf99

URL: https://github.com/llvm/llvm-project/commit/04b766dab0d9d786ab5695336348b0c01646cf99
DIFF: https://github.com/llvm/llvm-project/commit/04b766dab0d9d786ab5695336348b0c01646cf99.diff

LOG: [lldb/test] Deflake TestGdbRemote_vContThreads even more

This patch fixes an issue, where if the thread has a signal blocked when
we try to inject it into the process (via vCont), then instead of
executing straight away, the injected signal will trigger another stop
when the thread unblocks the signal.

As (linux) threads start their life with SIGUSR1 (among others)
disabled, and only enable it during initialization, injecting the signal
during this window did not behave as expected. The fix is to change the
test to ensure the signal gets injected with the signal unblocked.

The simplest way to do this was to write a dedicated inferior for this
test. I also created a new header to factor out the function retrieving
the (os-specific) thread id.

Added: 
    lldb/packages/Python/lldbsuite/test/make/thread.h
    lldb/test/API/tools/lldb-server/vCont-threads/Makefile
    lldb/test/API/tools/lldb-server/vCont-threads/TestGdbRemote_vContThreads.py
    lldb/test/API/tools/lldb-server/vCont-threads/main.cpp

Modified: 
    lldb/test/API/tools/lldb-server/main.cpp

Removed: 
    lldb/test/API/tools/lldb-server/TestGdbRemote_vContThreads.py


################################################################################
diff  --git a/lldb/packages/Python/lldbsuite/test/make/thread.h b/lldb/packages/Python/lldbsuite/test/make/thread.h
new file mode 100644
index 000000000000..3cfa16b84761
--- /dev/null
+++ b/lldb/packages/Python/lldbsuite/test/make/thread.h
@@ -0,0 +1,35 @@
+#ifndef LLDB_THREAD_H
+#define LLDB_THREAD_H
+
+#include <stdint.h>
+
+#if defined(__APPLE__)
+__OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2)
+int pthread_threadid_np(pthread_t, __uint64_t *);
+#elif defined(__linux__)
+#include <sys/syscall.h>
+#include <unistd.h>
+#elif defined(__NetBSD__)
+#include <lwp.h>
+#elif defined(_WIN32)
+#include <windows.h>
+#endif
+
+inline uint64_t get_thread_id() {
+#if defined(__APPLE__)
+  __uint64_t tid = 0;
+  pthread_threadid_np(pthread_self(), &tid);
+  return tid;
+#elif defined(__linux__)
+  return syscall(__NR_gettid);
+#elif defined(__NetBSD__)
+  // Technically lwpid_t is 32-bit signed integer
+  return static_cast<uint64_t>(_lwp_self());
+#elif defined(_WIN32)
+  return static_cast<uint64_t>(::GetCurrentThreadId());
+#else
+  return -1;
+#endif
+}
+
+#endif // LLDB_THREAD_H

diff  --git a/lldb/test/API/tools/lldb-server/main.cpp b/lldb/test/API/tools/lldb-server/main.cpp
index 8a14c11075f1..f719e4bc52f8 100644
--- a/lldb/test/API/tools/lldb-server/main.cpp
+++ b/lldb/test/API/tools/lldb-server/main.cpp
@@ -11,6 +11,7 @@
 #include <signal.h>
 #include <unistd.h>
 #endif
+#include "thread.h"
 #include <setjmp.h>
 #include <stdint.h>
 #include <stdio.h>
@@ -19,17 +20,6 @@
 #include <time.h>
 #include <vector>
 
-#if defined(__APPLE__)
-__OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2)
-int pthread_threadid_np(pthread_t, __uint64_t *);
-#elif defined(__linux__)
-#include <sys/syscall.h>
-#elif defined(__NetBSD__)
-#include <lwp.h>
-#elif defined(_WIN32)
-#include <windows.h>
-#endif
-
 static const char *const RETVAL_PREFIX = "retval:";
 static const char *const SLEEP_PREFIX = "sleep:";
 static const char *const STDERR_PREFIX = "stderr:";
@@ -70,26 +60,6 @@ static void print_pid() {
 #endif
 }
 
-static uint64_t get_thread_id() {
-// Put in the right magic here for your platform to spit out the thread id (tid)
-// that debugserver/lldb-gdbserver would see as a TID.
-#if defined(__APPLE__)
-  __uint64_t tid = 0;
-  pthread_threadid_np(pthread_self(), &tid);
-  return tid;
-#elif defined(__linux__)
-  // This is a call to gettid() via syscall.
-  return syscall(__NR_gettid);
-#elif defined(__NetBSD__)
-  // Technically lwpid_t is 32-bit signed integer
-  return static_cast<uint64_t>(_lwp_self());
-#elif defined(_WIN32)
-  return static_cast<uint64_t>(::GetCurrentThreadId());
-#else
-  return -1;
-#endif
-}
-
 static void signal_handler(int signo) {
 #if defined(_WIN32)
   // No signal support on Windows.

diff  --git a/lldb/test/API/tools/lldb-server/vCont-threads/Makefile b/lldb/test/API/tools/lldb-server/vCont-threads/Makefile
new file mode 100644
index 000000000000..32bbba57db6a
--- /dev/null
+++ b/lldb/test/API/tools/lldb-server/vCont-threads/Makefile
@@ -0,0 +1,5 @@
+CFLAGS_EXTRAS := -D__STDC_LIMIT_MACROS -D__STDC_FORMAT_MACROS
+ENABLE_THREADS := YES
+CXX_SOURCES := main.cpp
+
+include Makefile.rules

diff  --git a/lldb/test/API/tools/lldb-server/TestGdbRemote_vContThreads.py b/lldb/test/API/tools/lldb-server/vCont-threads/TestGdbRemote_vContThreads.py
similarity index 98%
rename from lldb/test/API/tools/lldb-server/TestGdbRemote_vContThreads.py
rename to lldb/test/API/tools/lldb-server/vCont-threads/TestGdbRemote_vContThreads.py
index 246a588db890..c7ced621c3f9 100644
--- a/lldb/test/API/tools/lldb-server/TestGdbRemote_vContThreads.py
+++ b/lldb/test/API/tools/lldb-server/vCont-threads/TestGdbRemote_vContThreads.py
@@ -10,8 +10,7 @@ class TestGdbRemote_vContThreads(gdbremote_testcase.GdbRemoteTestCaseBase):
     mydir = TestBase.compute_mydir(__file__)
 
     def start_threads(self, num):
-        procs = self.prep_debug_monitor_and_inferior(
-            inferior_args=['thread:new'] * num + ['@started'])
+        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",

diff  --git a/lldb/test/API/tools/lldb-server/vCont-threads/main.cpp b/lldb/test/API/tools/lldb-server/vCont-threads/main.cpp
new file mode 100644
index 000000000000..a0ac3ecc4f18
--- /dev/null
+++ b/lldb/test/API/tools/lldb-server/vCont-threads/main.cpp
@@ -0,0 +1,43 @@
+#include "pseudo_barrier.h"
+#include "thread.h"
+#include <chrono>
+#include <cinttypes>
+#include <csignal>
+#include <cstring>
+#include <thread>
+#include <unistd.h>
+#include <vector>
+
+pseudo_barrier_t barrier;
+
+static void sigusr1_handler(int signo) {
+  char buf[100];
+  snprintf(buf, sizeof(buf), "received SIGUSR1 on thread id: %" PRIx64 "\n",
+           get_thread_id());
+  write(STDOUT_FILENO, buf, strlen(buf));
+}
+
+static void thread_func() {
+  pseudo_barrier_wait(barrier);
+  std::this_thread::sleep_for(std::chrono::minutes(1));
+}
+
+int main(int argc, char **argv) {
+  int num = atoi(argv[1]);
+
+  pseudo_barrier_init(barrier, num + 1);
+
+  signal(SIGUSR1, sigusr1_handler);
+
+  std::vector<std::thread> threads;
+  for(int i = 0; i < num; ++i)
+    threads.emplace_back(thread_func);
+
+  pseudo_barrier_wait(barrier);
+
+  puts("@started");
+
+  for (std::thread &thread : threads)
+    thread.join();
+  return 0;
+}


        


More information about the lldb-commits mailing list