Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Which signal was delivered to process deadlocked in signal handler

I have a core dump from a process that deadlocked after invoking a signal handler. How do I determine which signal was delivered and who sent it?

The GDB-generated backtrace for the the thread that received the signal follows. The signal handler was called in frame 15.

(gdb) bt
#0  0x00007fa9c204654b in sys_futex (w=0x7fa9c2263d80, value=2, loop=<value optimized out>) at ./src/base/linux_syscall_support.h:1789
#1  base::internal::SpinLockDelay (w=0x7fa9c2263d80, value=2, loop=<value optimized out>) at ./src/base/spinlock_linux-inl.h:87
#2  0x00007fa9c204774c in SpinLock::SlowLock (this=0x7fa9c2263d80) at src/base/spinlock.cc:132
#3  0x00007fa9c2037ee3 in Lock (this=0x7fa9c2263d80, start=0x7fa9bb3c04c8, end=0x7fa9bb3c04c0, N=3) at src/base/spinlock.h:75
#4  tcmalloc::CentralFreeList::RemoveRange (this=0x7fa9c2263d80, start=0x7fa9bb3c04c8, end=0x7fa9bb3c04c0, N=3) at src/central_freelist.cc:247
#5  0x00007fa9c203bae4 in tcmalloc::ThreadCache::FetchFromCentralCache (this=0x17efb40, cl=<value optimized out>, byte_size=32) at src/thread_cache.cc:162
#6  0x00007fa9c202b9cb in Allocate (size=<value optimized out>) at src/thread_cache.h:341
#7  do_malloc (size=<value optimized out>) at src/tcmalloc.cc:1068
#8  (anonymous namespace)::do_malloc_or_cpp_alloc (size=<value optimized out>) at src/tcmalloc.cc:1005
#9  0x00007fa9c204bfa8 in tc_realloc (old_ptr=0x0, new_size=32) at src/tcmalloc.cc:1517
#10 0x0000003a358c0f3b in ?? () from /usr/lib64/libstdc++.so.6
#11 0x0000003a358c2adf in ?? () from /usr/lib64/libstdc++.so.6
#12 0x0000003a358c2cae in __cxa_demangle () from /usr/lib64/libstdc++.so.6
#13 0x000000000085f6c7 in my_print_stacktrace ()
#14 0x00000000006a773a in handle_fatal_signal ()
#15 <signal handler called>
#16 tcmalloc::CentralFreeList::FetchFromSpans (this=0x7fa9c2263d80) at src/central_freelist.cc:298
#17 0x00007fa9c2037f88 in tcmalloc::CentralFreeList::RemoveRange (this=0x7fa9c2263d80, start=0x7fa9bb3c1468, end=0x7fa9bb3c1460, N=3) at src/central_freelist.cc:269
#18 0x00007fa9c203bae4 in tcmalloc::ThreadCache::FetchFromCentralCache (this=0x17efb40, cl=<value optimized out>, byte_size=32) at src/thread_cache.cc:162
...

For what it's worth, handle_fatal_signal() and my_print_stacktrace() are MySQL functions. The rest are from Google's tcmalloc.

like image 533
Josh Avatar asked May 15 '14 13:05

Josh


People also ask

Does the kernel process automatically call the signal handlers?

The kernel does not automatically call signal handlers for a kernel process as it does for user processes. A kernel process should also use the exception-catching facilities (setjmpx, and clrjmpx) available in kernel mode to handle exceptions that can be caused during run time of the kernel process.

What is the name of the signal handler function?

A signal handler function can have any name, but must have return type void and have one int parameter. Example: you might choose the name sigchld_handler for a signal handler for the SIGCHLD signal (termination of a child process).

How do you know which signal was sent?

When a signal handler executes, the parameter passed to it is the number of the signal. A programmer can use the same signal handler function to handle several signals. In this case the handler would need to check the parameter to see which signal was sent.

What is signal handling by threads?

See Thread Signal Handlingfor more information on signal handling by threads. Signals whose action is applied at generation time (rather than delivery time) have the same effect regardless of whether the target is a kernel or user process.


1 Answers

I would try "frame 15" to move to the signal delivery frame, followed by "print $_siginfo.si_signo". See https://sourceware.org/gdb/onlinedocs/gdb/Signals.html

This works on Linux at least, which I presume from your backtrace that you are using. I'm not sure about other platforms.

like image 84
Tom Tromey Avatar answered Nov 15 '22 05:11

Tom Tromey