Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

runtime: sigaction problem when using cgo on FreeBSD #25745

Closed
billziss-gh opened this issue Jun 6, 2018 · 2 comments

Comments

Projects
None yet
2 participants
@billziss-gh
Copy link
Contributor

commented Jun 6, 2018

What version of Go are you using (go version)?

go version go1.10.1 freebsd/amd64

Does this issue reproduce with the latest release?

Likely.

What operating system and processor architecture are you using (go env)?

GOARCH="amd64"
GOBIN=""
GOCACHE="/home/billziss/.cache/go-build"
GOEXE=""
GOHOSTARCH="amd64"
GOHOSTOS="freebsd"
GOOS="freebsd"
GOPATH="/home/billziss/go"
GORACE=""
GOROOT="/usr/local/go"
GOTMPDIR=""
GOTOOLDIR="/usr/local/go/pkg/tool/freebsd_amd64"
GCCGO="gccgo"
CC="clang"
CXX="clang++"
CGO_ENABLED="1"
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build089165738=/tmp/go-build -gno-record-gcc-switches"

What did you do?

The following simple cgo program:

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"

func main() {
	C.sigprint(C.int(syscall.SIGTERM))
}

Succeeds (prints a non-0 signal handler) on Darwin and Linux:

$ go run sigbug.go
ret=0 handler=0x4034150

But fails (prints a 0 signal handler) on FreeBSD:

$ go run sigbug.go
ret=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.

Additional information at billziss-gh/cgofuse#18.

@billziss-gh billziss-gh changed the title runtime: sigaction problem when using cgo runtime: sigaction problem when using cgo on FreeBSD Jun 6, 2018

@ianlancetaylor

This comment has been minimized.

Copy link
Contributor

commented Jun 6, 2018

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.

@billziss-gh

This comment has been minimized.

Copy link
Contributor Author

commented Jun 6, 2018

Fantastic! I can confirm this is now fixed against the current tip:

$ go version
go version devel +2ce295e954 Wed Jun 6 01:47:31 2018 +0000 freebsd/amd64
$ go run sigbug.go
ret=0 handler=0x44a9c0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.