fibers: Invoke old sigsegv handler synchronously
Summary: folly::fibers uses a SIGSEGV handler to detect fiber overflows, by checking if the faulting address resides within a guard page range. In the case when it does not, prior to this diff, the folly::fibers signal handler would reraise the signal and allow the previous sigsegv handler handle the exception. The problem with this is that reraising the signal will discard the original `siginfo` context sent by the kernel. The old signal handler would lose visibility on the machine state, faulting condition, etc. This does not play nicely with folly::symbolizer. Typically, folly::symbolizer's signal handler will print information on the faulting signal, such as: ``` *** Signal 11 (SIGSEGV) (0xdeadbeef) received by PID 3140647 (pthread TID 0x7fe2cddf1380) (linux TID 3140647) (code: address not mapped to object), stack trace: *** @ 00000000002f4d3d folly::symbolizer::(anonymous namespace)::signalHandler(int, siginfo_t*, void*) ./folly/experimental/symbolizer/SignalHandler.cpp:449 @ 0000000000000000 (unknown) @ 00000000002dd0f9 doCrashWildRead() ./scripts/mingtao/oneoffs/crash.cc:9 @ 00000000002dd0b1 main ./scripts/mingtao/oneoffs/crash.cc:47 @ 0000000000025dc4 __libc_start_main @ 00000000002dcfb9 _start /home/engshare/third-party2/glibc/2.30/src/glibc-2.30/csu/../sysdeps/x86_64/start.S:120 Segmentation fault (core dumped) ``` From the error message, you can see that: * the faulting address was 0xdeadbeef * the reason for SIGSEGV was because the application accessed a region of memory outside of its virtual address space If you happened to have used `folly::fibers` somewhere within your application, though, you instead would see this: ``` *** Aborted at 1639532805 (Unix time, try 'date -d 1639532805') *** *** Signal 11 (SIGSEGV) (0x1c85b0032a0f8) received by PID 3318008 (pthread TID 0x7f5573e8d380) (linux TID 3318008) (maybe from PID 3318008, UID 116827) (code: -6), stack trace: *** @ 00000000002f4e0d folly::symbolizer::(anonymous namespace)::signalHandler(int, siginfo_t*, void*) ./folly/experimental/symbolizer/SignalHandler.cpp:449 @ 0000000000000000 (unknown) @ 00000000002dd169 doCrashWildRead() ./scripts/mingtao/oneoffs/crash.cc:9 @ 00000000002dd124 main ./scripts/mingtao/oneoffs/crash.cc:48 @ 0000000000025dc4 __libc_start_main @ 00000000002dcfb9 _start /home/engshare/third-party2/glibc/2.30/src/glibc-2.30/csu/../sysdeps/x86_64/start.S:120 ``` `code: -6` corresponds to `SI_TKILL`, indicating that the signal was a result of some process invoking `tgkill` (this is the fiber handler re-raising the signal) And `0x1c85b0032a0f8` is some bogus value, since signals raised by `tgkill` do not have a valid si_addr field. Furthermore, when debugging the core file, `p $_siginfo` will no longer give the relevant machine state at the time of the crash, since `$_siginfo` now would correspond to the raised signal by folly::fibers, rather than the original fault. This diff changes the `raise` to a synchronous invocation of the old signal handler. This allows the original signal context to be properly preserved (and visible within core). Reviewed By: Gownta Differential Revision: D33165801 fbshipit-source-id: 4526d5a9a93cf1eba13e9f5a16b13d00b3c8c85b
Showing
Please register or sign in to comment