Skip to content

safe_dump_to causes a deadlock if signal is received when throwing an exception #131

Closed
@tworonix

Description

@tworonix

Steps to reproduce

  1. Install a timer using standard Posix timer_create and SIGEV_SIGNAL
  2. Call safe_dump_to in the signal handler
  3. Throw C++ exceptions in the main code

Actual behavior:
The process deadlocks and hangs forever.

When investigating this issue I found out that throwing an exception in C++ involves locking a mutex (see here for more details: https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2544r0.html )

Apparently both throwing the exception and collecting the stacktrace from the signal handler try to lock the same mutex. This leads to a deadlock, or possibly also other undefined behaviour.

Unfortunately this makes safe_dump_to not so safe to call from a signal handler, which I find very bad news. I wish there was a way to get it to work reliably. I was using quite old versions, but I don't think this was fixed in any newer releases of gcc or boost?

Platform details

boost-1.66, Linux Intel x64, gcc-8.2.1, library compiled with BOOST_STACKTRACE_USE_ADDR2LINE

Output of gdb after loading the coredump of the deadlocked process

#0  0x00007fc0bf18c4ed in __lll_lock_wait () from /lib64/libpthread.so.0
#1  0x00007fc0bf187dcb in _L_lock_883 () from /lib64/libpthread.so.0
#2  0x00007fc0bf187c98 in pthread_mutex_lock () from /lib64/libpthread.so.0
#3  0x00007fc0bdcfca2a in _Unwind_Find_FDE () from /lib64/libgcc_s.so.1
#4  0x00007fc0bdcf9d2c in ?? () from /lib64/libgcc_s.so.1
#5  0x00007fc0bdcfa6ed in ?? () from /lib64/libgcc_s.so.1
#6  0x00007fc0bdcfaf88 in _Unwind_Backtrace () from /lib64/libgcc_s.so.1
#7  0x00000000004ee1bd in boost::stacktrace::detail::this_thread_frames::collect (out_frames=0xfdf180 <Contoso::sDump>, max_frames_count=<optimized out>, skip=<optimized out>) at /opt/Contoso/boost/dts9/1.66.0/include/boost/stacktrace/detail/collect_unwind.ipp:59
#8  0x00000000004ee16c in boost::stacktrace::detail::this_thread_frames::safe_dump_to_impl (memory=0xfdf180 <Contoso::sDump>, size=<optimized out>, skip=<optimized out>) at /opt/Contoso/boost/dts9/1.66.0/include/boost/stacktrace/safe_dump_to.hpp:55
#9  0x00000000004ed492 in boost::stacktrace::safe_dump_to (memory=0x7fc0bdf00360, size=256) at /opt/Contoso/boost/dts9/1.66.0/include/boost/stacktrace/safe_dump_to.hpp:90
#10 Contoso::(anonymous namespace)::HandleTimerSignal (signum=<optimized out>) at /opt/contoso/build-dir/source/libs/stacktrace/stack_trace.cc:24
#11 <signal handler called>
#12 0x00007fc0bf188e1b in pthread_mutex_unlock () from /lib64/libpthread.so.0
#13 0x00007fc0bdcfca7a in _Unwind_Find_FDE () from /lib64/libgcc_s.so.1
#14 0x00007fc0bdcf9d2c in ?? () from /lib64/libgcc_s.so.1
#15 0x00007fc0bdcfabd3 in _Unwind_RaiseException () from /lib64/libgcc_s.so.1
#16 0x00007fc0be261986 in __cxa_throw () from /lib64/libstdc++.so.6
#17 0x0000000000508820 in Contoso::ThrowingFunction 

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions