llvm / llvm-project

The LLVM Project is a collection of modular and reusable compiler and toolchain technologies.
http://llvm.org
Other
28.47k stars 11.77k forks source link

pthread_cancel results in SEGFAULT with libc++ #90041

Open nolange opened 5 months ago

nolange commented 5 months ago

libunwind / libc++ / clang : 18.1.2-1 from debian libgcc : 12.2.0-14 from debian

The following program will reproduce the SEGFAULT:

// compile with: clang++ -stdlib=libc++ test_cancel.cpp

#include <pthread.h>
#include <thread>
extern "C" int main()
{
    std::thread systhr([]() { std::this_thread::sleep_for(std::chrono::seconds(10000)); });

    std::this_thread::sleep_for(std::chrono::seconds(1));
    pthread_cancel(systhr.native_handle());

    systhr.join();
    return 0;
}

adding -rtlib=compiler-rt and/or -unwindlib=libgcc did not affect the issue, removing stdlib=libc++ fixes the problem.

I tried replicating the issue with a C program and LD_PRELOAD="libc++.so.1:libc++abi.so.1:libunwind.so.1:libgcc_s.so.1" but did not manage to reproduce

Runtime dependencies are:

 0x0000000000000001 (NEEDED)             Shared library: [libc++.so.1]
 0x0000000000000001 (NEEDED)             Shared library: [libc++abi.so.1]
 0x0000000000000001 (NEEDED)             Shared library: [libunwind.so.1]
 0x0000000000000001 (NEEDED)             Shared library: [libm.so.6]
 0x0000000000000001 (NEEDED)             Shared library: [libgcc_s.so.1]
 0x0000000000000001 (NEEDED)             Shared library: [libc.so.6]

Stacktrace:

Thread 2 "a.out" received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x7ffff7b7b6c0 (LWP 102805)]
0x0000000000000000 in ?? ()
(gdb) bt
#0  0x0000000000000000 in ?? ()
#1  0x00007ffff7e6799c in unw_get_proc_info () from /lib/x86_64-linux-gnu/libunwind.so.1
#2  0x00007ffff7e6ce82 in _Unwind_GetLanguageSpecificData () from /lib/x86_64-linux-gnu/libunwind.so.1
#3  0x00007ffff7ea5cf0 in __gxx_personality_v0 () from /lib/x86_64-linux-gnu/libc++abi.so.1
#4  0x00007ffff7d78ab6 in _Unwind_ForcedUnwind_Phase2 (exc=exc@entry=0x7ffff7b7bd30, context=context@entry=0x7ffff7b7a550, frames_p=frames_p@entry=0x7ffff7b7a458) at ../../../src/libgcc/unwind.inc:183
#5  0x00007ffff7d791b0 in _Unwind_ForcedUnwind (exc=0x7ffff7b7bd30, stop=0x7ffff7c102c0 <unwind_stop>, stop_argument=<optimized out>) at ../../../src/libgcc/unwind.inc:218
#6  0x00007ffff7c10440 in __GI___pthread_unwind (buf=<optimized out>) at ./nptl/unwind.c:130
#7  0x00007ffff7c0673b in __do_cancel () at ../sysdeps/nptl/pthreadP.h:282
#8  sigcancel_handler (sig=32, si=0x7ffff7b7a7f0, ctx=<optimized out>) at ./nptl/pthread_cancel.c:65
#9  sigcancel_handler (sig=<optimized out>, si=0x7ffff7b7a7f0, ctx=<optimized out>) at ./nptl/pthread_cancel.c:32
#10 <signal handler called>
#11 0x00007ffff7c4e485 in __GI___clock_nanosleep (clock_id=clock_id@entry=0, flags=flags@entry=0, req=0x7ffff7b7adb8, rem=0x7ffff7b7adb8) at ../sysdeps/unix/sysv/linux/clock_nanosleep.c:48
#12 0x00007ffff7c52d93 in __GI___nanosleep (req=<optimized out>, rem=<optimized out>) at ../sysdeps/unix/sysv/linux/nanosleep.c:25
#13 0x00007ffff7f4bbab in std::__1::this_thread::sleep_for(std::__1::chrono::duration<long long, std::__1::ratio<1l, 1000000000l> > const&) () from /lib/x86_64-linux-gnu/libc++.so.1
#14 0x000055555555595e in void std::__1::this_thread::sleep_for[abi:ne180100]<long long, std::__1::ratio<1l, 1l> >(std::__1::chrono::duration<long long, std::__1::ratio<1l, 1l> > const&) ()
#15 0x0000555555555709 in main::$_0::operator()() const ()
#16 0x00005555555556b5 in decltype (((std::declval<main::$_0>)())()) std::__1::__invoke[abi:ne180100]<main::$_0>(main::$_0&&) ()
#17 0x000055555555568d in _ZNSt3__116__thread_executeB8ne180100INS_10unique_ptrINS_15__thread_structENS_14default_deleteIS2_EEEEZ4mainE3$_0JETpTnmJEEEvRNS_5tupleIJT_T0_DpT1_EEENS_15__tuple_indicesIJXspT2_EEEE
    ()
#18 0x00005555555554d2 in void* std::__1::__thread_proxy[abi:ne180100]<std::__1::tuple<std::__1::unique_ptr<std::__1::__thread_struct, std::__1::default_delete<std::__1::__thread_struct> >, main::$_0> >(void*)
    ()
#19 0x00007ffff7c08134 in start_thread (arg=<optimized out>) at ./nptl/pthread_create.c:442
#20 0x00007ffff7c887dc in clone3 () at ../sysdeps/unix/sysv/linux/x86_64/clone3.S:81
nolange commented 5 months ago

probably more related to libunwind or libc++-abi. dont think I can add labels?

nolange commented 5 months ago

replicated with a base debian bookworm container using clang/libc++/libunwind version 14. This also means a more complete stacktrace:

#0  0x0000000000000000 in ?? ()
#1  0x00007f70fc3b1baa in unw_get_proc_info () at build-llvm/tools/clang/stage2-bins/runtimes/runtimes-bins/libunwind/src/libunwind.cpp:188
#2  0x00007f70fc3b588c in _Unwind_GetLanguageSpecificData () at build-llvm/tools/clang/stage2-bins/runtimes/runtimes-bins/libunwind/src/UnwindLevel1.c:478
#3  0x00007f70fc3a001d in scan_eh_tab () at build-llvm/tools/clang/stage2-bins/runtimes/runtimes-bins/libcxxabi/src/cxa_personality.cpp:617
#4  __gxx_personality_v0 () at build-llvm/tools/clang/stage2-bins/runtimes/runtimes-bins/libcxxabi/src/cxa_personality.cpp:947
#5  0x00007f70fc28fab6 in _Unwind_ForcedUnwind_Phase2 (exc=exc@entry=0x7f70fc092d30, context=context@entry=0x7f70fc091650, 
    frames_p=frames_p@entry=0x7f70fc091558) at ../../../src/libgcc/unwind.inc:183
#6  0x00007f70fc2901b0 in _Unwind_ForcedUnwind (exc=0x7f70fc092d30, stop=0x7f70fc1272c0 <unwind_stop>, stop_argument=<optimized out>)
    at ../../../src/libgcc/unwind.inc:218
#7  0x00007f70fc127440 in __GI___pthread_unwind (buf=<optimized out>) at ./nptl/unwind.c:130
#8  0x00007f70fc11d73b in __do_cancel () at ../sysdeps/nptl/pthreadP.h:282
#9  sigcancel_handler (sig=32, si=0x7f70fc0918f0, ctx=<optimized out>) at ./nptl/pthread_cancel.c:65
#10 sigcancel_handler (sig=<optimized out>, si=0x7f70fc0918f0, ctx=<optimized out>) at ./nptl/pthread_cancel.c:32
#11 <signal handler called>
#12 0x00007f70fc165485 in __GI___clock_nanosleep (clock_id=clock_id@entry=0, flags=flags@entry=0, req=0x7f70fc091db8, rem=0x7f70fc091db8)
    at ../sysdeps/unix/sysv/linux/clock_nanosleep.c:48
#13 0x00007f70fc169d93 in __GI___nanosleep (req=<optimized out>, rem=<optimized out>) at ../sysdeps/unix/sysv/linux/nanosleep.c:25
#14 0x00007f70fc41df9b in __libcpp_thread_sleep_for () at build-llvm/tools/clang/stage2-bins/include/c++/v1/__threading_support:411
#15 sleep_for () at build-llvm/tools/clang/stage2-bins/runtimes/runtimes-bins/libcxx/src/thread.cpp:108
#16 0x000055bf7ab29a5e in void std::__1::this_thread::sleep_for<long long, std::__1::ratio<1l, 1l> >(std::__1::chrono::duration<long long, std::__1::ratio<1l, 1l> > const&) ()
#17 0x000055bf7ab297fd in main::$_0::operator()() const ()
#18 0x000055bf7ab29795 in decltype ((static_cast<main::$_0>({parm#1}))()) std::__1::__invoke<main::$_0>(main::$_0&&) ()
#19 0x000055bf7ab29775 in void std::__1::__thread_execute<std::__1::unique_ptr<std::__1::__thread_struct, std::__1::default_delete<std::__1::__thread_struct> >, main::$_0>(std::__1::tuple<std::__1::unique_ptr<std::__1::__thread_struct, std::__1::default_delete<std::__1::__thread_struct> >, main::$_0>&, std::__1::__tuple_indices<>) ()
#20 0x000055bf7ab29532 in void* std::__1::__thread_proxy<std::__1::tuple<std::__1::unique_ptr<std::__1::__thread_struct, std::__1::default_delete<std::__1::__thread_struct> >, main::$_0> >(void*) ()
#21 0x00007f70fc11f134 in start_thread (arg=<optimized out>) at ./nptl/pthread_create.c:442
#22 0x00007f70fc19f7dc in clone3 () at ../sysdeps/unix/sysv/linux/x86_64/clone3.S:81