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; +} _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits