Skip to content

Commit a4e0062

Browse files
labathmemfrob
authored andcommitted
[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.
1 parent 80ae399 commit a4e0062

File tree

5 files changed

+85
-33
lines changed

5 files changed

+85
-33
lines changed
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
#ifndef LLDB_THREAD_H
2+
#define LLDB_THREAD_H
3+
4+
#include <stdint.h>
5+
6+
#if defined(__APPLE__)
7+
__OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2)
8+
int pthread_threadid_np(pthread_t, __uint64_t *);
9+
#elif defined(__linux__)
10+
#include <sys/syscall.h>
11+
#include <unistd.h>
12+
#elif defined(__NetBSD__)
13+
#include <lwp.h>
14+
#elif defined(_WIN32)
15+
#include <windows.h>
16+
#endif
17+
18+
inline uint64_t get_thread_id() {
19+
#if defined(__APPLE__)
20+
__uint64_t tid = 0;
21+
pthread_threadid_np(pthread_self(), &tid);
22+
return tid;
23+
#elif defined(__linux__)
24+
return syscall(__NR_gettid);
25+
#elif defined(__NetBSD__)
26+
// Technically lwpid_t is 32-bit signed integer
27+
return static_cast<uint64_t>(_lwp_self());
28+
#elif defined(_WIN32)
29+
return static_cast<uint64_t>(::GetCurrentThreadId());
30+
#else
31+
return -1;
32+
#endif
33+
}
34+
35+
#endif // LLDB_THREAD_H

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

Lines changed: 1 addition & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include <signal.h>
1212
#include <unistd.h>
1313
#endif
14+
#include "thread.h"
1415
#include <setjmp.h>
1516
#include <stdint.h>
1617
#include <stdio.h>
@@ -19,17 +20,6 @@
1920
#include <time.h>
2021
#include <vector>
2122

22-
#if defined(__APPLE__)
23-
__OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2)
24-
int pthread_threadid_np(pthread_t, __uint64_t *);
25-
#elif defined(__linux__)
26-
#include <sys/syscall.h>
27-
#elif defined(__NetBSD__)
28-
#include <lwp.h>
29-
#elif defined(_WIN32)
30-
#include <windows.h>
31-
#endif
32-
3323
static const char *const RETVAL_PREFIX = "retval:";
3424
static const char *const SLEEP_PREFIX = "sleep:";
3525
static const char *const STDERR_PREFIX = "stderr:";
@@ -70,26 +60,6 @@ static void print_pid() {
7060
#endif
7161
}
7262

73-
static uint64_t get_thread_id() {
74-
// Put in the right magic here for your platform to spit out the thread id (tid)
75-
// that debugserver/lldb-gdbserver would see as a TID.
76-
#if defined(__APPLE__)
77-
__uint64_t tid = 0;
78-
pthread_threadid_np(pthread_self(), &tid);
79-
return tid;
80-
#elif defined(__linux__)
81-
// This is a call to gettid() via syscall.
82-
return syscall(__NR_gettid);
83-
#elif defined(__NetBSD__)
84-
// Technically lwpid_t is 32-bit signed integer
85-
return static_cast<uint64_t>(_lwp_self());
86-
#elif defined(_WIN32)
87-
return static_cast<uint64_t>(::GetCurrentThreadId());
88-
#else
89-
return -1;
90-
#endif
91-
}
92-
9363
static void signal_handler(int signo) {
9464
#if defined(_WIN32)
9565
// No signal support on Windows.
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
CFLAGS_EXTRAS := -D__STDC_LIMIT_MACROS -D__STDC_FORMAT_MACROS
2+
ENABLE_THREADS := YES
3+
CXX_SOURCES := main.cpp
4+
5+
include Makefile.rules

lldb/test/API/tools/lldb-server/TestGdbRemote_vContThreads.py renamed to lldb/test/API/tools/lldb-server/vCont-threads/TestGdbRemote_vContThreads.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,7 @@ class TestGdbRemote_vContThreads(gdbremote_testcase.GdbRemoteTestCaseBase):
1010
mydir = TestBase.compute_mydir(__file__)
1111

1212
def start_threads(self, num):
13-
procs = self.prep_debug_monitor_and_inferior(
14-
inferior_args=['thread:new'] * num + ['@started'])
13+
procs = self.prep_debug_monitor_and_inferior(inferior_args=[str(num)])
1514
# start the process and wait for output
1615
self.test_sequence.add_log_lines([
1716
"read packet: $c#63",
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
#include "pseudo_barrier.h"
2+
#include "thread.h"
3+
#include <chrono>
4+
#include <cinttypes>
5+
#include <csignal>
6+
#include <cstring>
7+
#include <thread>
8+
#include <unistd.h>
9+
#include <vector>
10+
11+
pseudo_barrier_t barrier;
12+
13+
static void sigusr1_handler(int signo) {
14+
char buf[100];
15+
snprintf(buf, sizeof(buf), "received SIGUSR1 on thread id: %" PRIx64 "\n",
16+
get_thread_id());
17+
write(STDOUT_FILENO, buf, strlen(buf));
18+
}
19+
20+
static void thread_func() {
21+
pseudo_barrier_wait(barrier);
22+
std::this_thread::sleep_for(std::chrono::minutes(1));
23+
}
24+
25+
int main(int argc, char **argv) {
26+
int num = atoi(argv[1]);
27+
28+
pseudo_barrier_init(barrier, num + 1);
29+
30+
signal(SIGUSR1, sigusr1_handler);
31+
32+
std::vector<std::thread> threads;
33+
for(int i = 0; i < num; ++i)
34+
threads.emplace_back(thread_func);
35+
36+
pseudo_barrier_wait(barrier);
37+
38+
puts("@started");
39+
40+
for (std::thread &thread : threads)
41+
thread.join();
42+
return 0;
43+
}

0 commit comments

Comments
 (0)