Closed
Description
What version of Go are you using (go version
)?
$ go version 1.16.3
Does this issue reproduce with the latest release?
Yes
What operating system and processor architecture are you using (go env
)?
go env
Output
$ go env GO111MODULE="" GOARCH="amd64" GOBIN="" GOCACHE="/root/.cache/go-build" GOENV="/root/.config/go/env" GOEXE="" GOFLAGS="" GOHOSTARCH="amd64" GOHOSTOS="linux" GOINSECURE="" GOMODCACHE="/root/go/pkg/mod" GONOPROXY="" GONOSUMDB="" GOOS="linux" GOPATH="/root/go" GOPRIVATE="" GOPROXY="https://proxy.golang.org,direct" GOROOT="/usr/local/go" GOSUMDB="sum.golang.org" GOTMPDIR="" GOTOOLDIR="/usr/local/go/pkg/tool/linux_amd64" GOVCS="" GOVERSION="go1.16.3" GCCGO="gccgo" AR="ar" CC="gcc" CXX="g++" CGO_ENABLED="1" GOMOD="/root/tmp-curiosity-segv/go.mod" 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 -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build37738244=/tmp/go-build -gno-record-gcc-switches"
What did you do?
// cgosignal.go
// Run with: go run cgosignal.go & sleep 1; kill -USR1 %%
package main
/*
#include <stdio.h>
#include <signal.h>
#include <stdlib.h>
#include <unistd.h>
extern double asin(double);
extern double acos(double);
static void sighandler(int signum) {
fprintf(stderr, "Signal caught, exiting!\n");
fprintf(stderr, "acos = %lf\n", acos(3.14));
fprintf(stderr, "Past Go call!\n");
exit(0);
}
static void main() {
struct sigaction sigact;
sigact.sa_handler = sighandler;
sigemptyset(&sigact.sa_mask);
sigact.sa_flags = 0;
sigaction(SIGUSR1, &sigact, NULL);
fprintf(stderr, "Loaded; waiting for SIGUSR1\n");
acos(3.14);
asin(3.14);
sleep(0xFFFFFFFF);
}
*/
import "C"
//export asin
func asin(x C.double) C.double {
for {}
return x
}
//export acos
func acos(x C.double) C.double {
return x
}
func main() {
C.main()
}
What did you expect to see?
[1] 27268
Loaded; waiting for SIGUSR1
Signal caught, exiting!
acos = 3.14
Past Go call!
exit status 0
[1]+ Exit 0 go run cgosignal.go
What did you see instead?
[1] 27268
Loaded; waiting for SIGUSR1
Signal caught, exiting!
unexpected fault address 0xfffffffffffffff8
fatal: morestack on g0
SIGTRAP: trace trap
PC=0x45ce02 m=0 sigcode=128
signal arrived during cgo execution
goroutine 1 [running, locked to thread]:
runtime.abort()
/usr/local/go/src/runtime/asm_amd64.s:854 +0x2 fp=0xc00004a750 sp=0xc00004a748 pc=0x45ce02
runtime.morestack()
/usr/local/go/src/runtime/asm_amd64.s:425 +0x25 fp=0xc00004a758 sp=0xc00004a750 pc=0x45b2c5
rax 0x17
rbx 0x6d8840
rcx 0x45e675
rdx 0x17
rdi 0x2
rsi 0x47d19a
rbp 0xc00004a720
rsp 0xc00004a748
r8 0x1
r9 0x706280
r10 0x0
r11 0x202
r12 0xf2
r13 0x0
r14 0x48fd98
r15 0x0
rip 0x45ce02
rflags 0x206
cs 0x33
fs 0x0
gs 0x0
exit status 2
[1]+ Exit 1 go run cgosignal.go
Notes
I was trying to help out @paultag (https://twitter.com/paultag/status/1380617072921677828) and managed to reproduce the issue without shared libraries involved, just plain cgo signal handler calling Go code.
The only maybe-related issue I found was #19465 (I'm suspecting something to do with async-signal-safety) which is why I did the repro with SIGUSR1 and not SIGINT (which also has the issue).