Search code examples
xcodesignalslldb

lldb not properly forwarding `siginfo_t` to attached process signal handler


I previously asked this question, and discovered that lldb will not passthough the data from the siginfo_t struct from the original signal; everything is 0'd out except the signal number. The signals and data in siginfo_t work as expected when the program is not being debugged.

I'm using the process handle subcommand in lldb to ensure passthough is enabled for SIGTERM but this doesnt seem to work (or at least not as I expect). I dont know if this applies to all signals, but I'm specifically interested in SIGTERM.

Is this a bug in lldb? Is there a way to control this behavior? I see nothing in the help.

I'm on macOS 10.14.1 (Mojave) and Xcode 10 (lldb-1000.11.37.1) if that matters.


Solution

  • lldb can't directly invoke your signal handler. There isn't a "signals.h" way that I know of on MacOS for one process to send a signal including the targeted thread and any other info to another process. All the pthread_kill variants are local process only.

    Instead, the debugger intercepts the signal prior to its actual delivery by getting an EXC_SOFTWARE/EXC_SOFT_SIGNAL Mach exception. Then on resume, it tells the kernel to propagate the signal with the ptrace system utility - using "PT_THUPDATE". That define is in usr/include/sys/ptrace.h. With PT_THUPDATE, you send the signal number and the kernel treats it as if the original signal was suppressed, and a new signal raised.

    This process is lossy. Initially, lldb only receives the signal number and the targeted thread, and not any of the other information. Also, PT_THUPDATE API only takes a thread ID and a signal number. So we have no way to forward more info even if we had it.

    The kernel would have to keep all the other info around and when lldb forwards the signal, copy it over, or provide API's for lldb to fetch and resend this info along with the signal.