You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
package main
/*#include <stdio.h>#include <signal.h>static void sigprint(int sig) { struct sigaction sa; int ret = sigaction(sig, 0, &sa); fprintf(stderr, "ret=%d handler=%p\n", ret, sa.sa_handler);}*/import"C"import"syscall"funcmain() {
C.sigprint(C.int(syscall.SIGTERM))
}
Succeeds (prints a non-0 signal handler) on Darwin and Linux:
$ go run sigbug.goret=0 handler=0x4034150
But fails (prints a 0 signal handler) on FreeBSD:
$ go run sigbug.goret=0 handler=0x0
What did you expect to see?
I expected to see the signal handler that the go runtime installs.
What did you see instead?
The C sigaction function thinks that there is no signal handler.
Investigation
I believe the reason for the "mysterious" sigaction behavior is that the Go runtime invokes sigaction using SYSCALL. However FreeBSD expects that C (and cgo) programs should use the libc sigaction, which is "interposed" by libthr to __thr_sigaction. Libthr maintains its own copy of sigaction's and overrides what the kernel returns.
A likely fix for this is to do what Linux does for sigaction. Invoke it using SYSCALL if "!cgo" or use the C library sigaction if "cgo". See rt_sigaction.
I believe that this is already fixed on tip and therefore in the upcoming 1.11 release as part of the work on #14327. I'm going to close this issue but please do comment if I turn out to be mistaken.
What version of Go are you using (
go version
)?Does this issue reproduce with the latest release?
Likely.
What operating system and processor architecture are you using (
go env
)?What did you do?
The following simple cgo program:
Succeeds (prints a non-0 signal handler) on Darwin and Linux:
But fails (prints a 0 signal handler) on FreeBSD:
What did you expect to see?
I expected to see the signal handler that the go runtime installs.
What did you see instead?
The C
sigaction
function thinks that there is no signal handler.Investigation
I believe the reason for the "mysterious"
sigaction
behavior is that the Go runtime invokessigaction
usingSYSCALL
. However FreeBSD expects that C (and cgo) programs should use the libcsigaction
, which is "interposed" by libthr to__thr_sigaction
. Libthr maintains its own copy ofsigaction
's and overrides what the kernel returns.A likely fix for this is to do what Linux does for
sigaction
. Invoke it usingSYSCALL
if "!cgo" or use the C librarysigaction
if "cgo". Seert_sigaction
.Additional information at billziss-gh/cgofuse#18.
The text was updated successfully, but these errors were encountered: