I have a nearly-reduced test case which livelocks fairly predictably, but only on Ubuntu 18.04, not on 19.10 or 20.04 alpha. gcc --version reports gcc (Ubuntu 7.4.0-1ubuntu1~18.04.1) 7.4.0 The script #!/bin/sh set -ex gcc -g -O2 -fsanitize=address -pthread bug.i -lssl -o bug export ASAN_OPTIONS=detect_stack_use_after_return=1 export LSAN_OPTIONS=verbosity=1 for iter in $(seq 1 1000) do ./bug done echo "No hang found." triggers the hang reliably for me in under a minute. Now that I know turning off LSAN_OPTIONS=verbosity=1 makes the hang go away, I'm not really worried about it, but I am still wondering why the problem goes away in ubuntu 19.10. (Was it an accidental fix, or is this a known bug that has been fixed?) ps shows the test case using all of one core: buildbot 20292 98.3 0.0 21474948752 11116 pts/4 Rl+ 22:12 0:58 ./bug gdb bt shows __sanitizer::internal_sched_yield () at ../../../../src/libsanitizer/sanitizer_common/sanitizer_linux.cc:332 332 ../../../../src/libsanitizer/sanitizer_common/sanitizer_linux.cc: No such file or directory. #0 __sanitizer::internal_sched_yield () at ../../../../src/libsanitizer/sanitizer_common/sanitizer_linux.cc:332 #1 0x00007f7d348a6e95 in __interceptor_pthread_create (thread=0x7f7d2fb00060, attr=<optimized out>, start_routine=0x55b8cb83b470 <thread_main>, arg=0x0) at ../../../../src/libsanitizer/asan/asan_interceptors.cc:273 #2 0x000055b8cb83b67d in do_work () at bug.c:48 #3 0x000055b8cb83b28d in create_children () at bug.c:88 #4 main (argc=<optimized out>, argv=<optimized out>) at bug.c:106 I suppose I could finish reducing the test case by pulling the source for SSL_CTX_new() into my .i and letting c-reduce run wild, but first I thought I'd ask if this rings a bell. Here's the mostly-reduced test case. -- snip -- static int readers = 40; static int once_control = 0; static int test_secs = 1; typedef int pid_t; struct timeval { long tv_sec; long tv_usec; }; struct timespec { long tv_sec; long tv_nsec; }; typedef unsigned long int pthread_t; enum __itimer_which { ITIMER_REAL, }; struct itimerval { struct timeval it_interval; struct timeval it_value; }; typedef int sig_atomic_t; typedef void(*__sighandler_t); struct sigaction { struct { __sighandler_t sa_handler; } __sigaction_handler; }; typedef struct ssl_ctx_st SSL_CTX; typedef struct ssl_method_st SSL_METHOD; static SSL_CTX *context; static struct timespec start_time; static struct timespec goal_end_time; static volatile sig_atomic_t keep_on_chugging = 1; void do_once() { const struct ssl_method_st *p = 0; SSL_CTX *context = SSL_CTX_new(p); } void thread_main(void *v) { } void do_work() { pthread_t net_5; pthread_once(&once_control, do_once); pthread_create(&net_5, 0, thread_main, 0); } static _Bool is_time_to_quit(void) { struct timespec now_time; clock_gettime(0, &now_time); long long remaining_nsecs = (goal_end_time.tv_sec - now_time.tv_sec) * 1000000000ULL; remaining_nsecs += goal_end_time.tv_nsec - now_time.tv_nsec; if (remaining_nsecs < 0) return 1; return 0; } static void set_flag_for_exit(int signo) { if (is_time_to_quit()) keep_on_chugging = 0; } static void set_timer(void) { struct itimerval iv = {{0}, {0}}; iv.it_value.tv_usec = 3000; iv.it_interval.tv_usec = 3000; if (setitimer(ITIMER_REAL, &iv, ((void *)0)) < 0) abort(); if (is_time_to_quit()) exit(0); } static void create_children(void) { int i; struct sigaction act; memset(&act, 0, sizeof(act)); act.__sigaction_handler.sa_handler = set_flag_for_exit; sigaction(14, &act, ((void *)0)); act.__sigaction_handler.sa_handler = ((__sighandler_t)1); pid_t pid; for (i = 0; i < readers; i++) { if (i < readers) { if ((pid = fork()) < 0) abort(); if (pid == 0) { set_timer(); do_work(); _exit(0); } } } } static int reap_children(void) { int i; int status; for (i = 0; i < readers; i++) wait(&status); } int main(int argc, char *argv[]) { clock_gettime(0, &start_time); goal_end_time = start_time; goal_end_time.tv_sec += test_secs; create_children(); reap_children(); } -- snip --