CRASH with multiple native handlers after vfork child exits
DynamoRIO 9.0.1 and trunk crash with an error about "multiple native handlers", in cases involving a sigaction after a vfork or clone:
#include <signal.h>
#include <unistd.h>
int main ()
{
int r;
static struct sigaction sa;
sigaction (SIGUSR1, 0, &sa);
r = vfork();
if (r == 0) _exit(1);
sigaction (SIGUSR1, &sa, 0);
return 0;
}
$ DynamoRIO-AArch64-Linux-9.0.1/bin64/drrun -- ./a.out
<Application /home/agrant/gcscheck/a.out (9637). Cannot correctly handle received signal 11 in thread 9637: multiple native handlers.>
Signal 11 is SIGSEGV.
$ DynamoRIO-AArch64-Linux-9.0.1/bin64/drrun -debug -- ./a.out
<Starting application /home/agrant/gcscheck/a.out (9635)>
<Initial options = -no_dynamic_options -code_api -stack_size 56K -signal_stack_size 32K -max_elide_jmp 0 -max_elide_call 0 -early_inject -emulate_brk -no_inline_ignored_syscalls -native_exec_default_list '' -no_native_exec_managed_code -no_indcall2direct >
<Paste into GDB to debug DynamoRIO clients:
set confirm off
add-symbol-file '/home/agrant/gcscheck/DynamoRIO-AArch64-Linux-9.0.1/lib64/debug/libdynamorio.so' 0x0000000071015e18
>
<(1+x) Handling our fault in a TRY at 0x000000007137726c>
<Application /home/agrant/gcscheck/a.out (9635). Cannot correctly handle received signal 17 in thread 9635: multiple native handlers.>
Signal 17 is SIGCHLD.
Looking at core/unix/signal.c, the comment around this failure refers to another comment:
... i#1921: To properly handle multiple separate signal handler thread groups
* within this single DR process domain, we would need a list of these, along with
* lists of threads within each. Since that is very rare, and requires either
* hardcoded maximums or complexities with exit-time heap, we currently do not
* support that and die if asked to deliver a native signal in such circumstances.
But that doesn't seem relevant to this test case, which was extracted from posix_spawn() in glibc.