Le 04/02/2020 à 01:03, Josh Kunz a écrit : > On Sat, Feb 1, 2020 at 4:27 AM Laurent Vivier <laur...@vivier.eu> wrote: >> This has been tested with Go (golang 1.10.1 linux/arm64, bionic) on x86_64 >> fedora 31. We can avoid the failure in this case allowing the unsupported >> signals when we don't provide the "act" parameters to sigaction, only the >> "oldact" one. I have also run the LTP suite with several target and debian >> based distros. > > This breaks with go1.13+ (I also verified at hash 753d56d364)[1]. I > tested using an aarch64 guest on an x86 system, but this should > manifest on any architecture when the guest/host have the same number > of signals (and glibc reserves some host signals). From the traceback, > you can see it dies in `initsig` which is called at startup. Any Go > program should fail.
I reproduced the problem with aarch64/eoan, go1.12.10. Thank you. > Since go does not use a libc, it assumes that all signals from > [1.._NSIG) are available[2], and will panic if it cannot do an > rt_sigaction for all of them. Go already has some special handling for > QEMU where it silently discards failing rt_sigaction calls to signals > 32, 33, and 64 [3]. Since this patch reserves an extra signal for > __SIGRTMIN+1 as well, it blocks out guest signal 63 and Go fails to > initialize. We should add signal 63 here, but it's becoming not very clean. > While I personally support this patch series (current handling of > guest glibc signals is broken), it *will* break Go binaries. I don't > know of a way to avoid this while supporting guest __SIGRTMIN+1, > without either doing true signal multiplexing, or patching Go. I think we could also simply ignore the error. As returning an error is generally an abort condition even if the signal is never used, and it's what we would do in go to avoid the problem. We will have problem later with programs that really want to use the signal but I don't think we can do better (do we know programs using 31 RT signals? or starting by the end of the list?). something like: diff --git a/linux-user/signal.c b/linux-user/signal.c index c4abacde49a0..169a84afe90b 100644 --- a/linux-user/signal.c +++ b/linux-user/signal.c @@ -866,8 +866,8 @@ int do_sigaction(int sig, const struct target_sigaction *act, trace_signal_do_sigaction_host(host_sig, TARGET_NSIG); if (host_sig > SIGRTMAX) { /* we don't have enough host signals to map all target signals */ - qemu_log_mask(LOG_UNIMP, "Unsupported target signal #%d\n", sig); - return -TARGET_EINVAL; + qemu_log_mask(LOG_UNIMP, "Unsupported target signal #%d, ignored", sig); + return 0; } Thanks, Laurent