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

gccgo: undocumented signal mask change #22723

Closed
xry111 opened this issue Nov 14, 2017 · 1 comment
Closed

gccgo: undocumented signal mask change #22723

xry111 opened this issue Nov 14, 2017 · 1 comment

Comments

@xry111
Copy link

xry111 commented Nov 14, 2017

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

go version go1.8.1 gccgo (GCC) 7.2.1 20170821 linux/amd64

Does this issue reproduce with the latest release?

It doesn't reproduce with later gc toolchains:
go version go1.8.5 linux/amd64
go version go1.9.2 linux/amd64

So it seems it's a gccgo issue.

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

GOARCH="amd64"
GOBIN=""
GOEXE=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOOS="linux"
GOPATH="/home/xry111/go"
GORACE=""
GOROOT="/usr"
GOTOOLDIR="/usr/lib64/gcc/x86_64-pc-linux-gnu/7.2.1"
GCCGO="/usr/bin/gccgo-7.2"
CC="/usr/bin/gcc-7.2"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build361560552=/tmp/go-build -gno-record-gcc-switches"
CXX="/usr/bin/g++-7.2"
CGO_ENABLED="1"
PKG_CONFIG="pkg-config"
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"

What did you do?

(1) Use cgo to mask SIGINT before Go initialize routine runs.
(2) Create a pthread with cgo, to get SIGINTs with sigwaitinfo.
(3) Run the program (attached) and press Ctrl+C in terminal (or kill -INT it).

package main

/*
#cgo CFLAGS: -pthread
#cgo LDFLAGS: -pthread
#include <pthread.h>
#include <signal.h>
#include <stdio.h>

__attribute__((constructor))
static void init(void) {
	sigset_t sset;
	struct sigevent sigev;
	struct sigaction sigact;
	struct itimerspec spec;

	sigemptyset(&sset);
	sigaddset(&sset, SIGINT);
	pthread_sigmask(SIG_BLOCK, &sset, NULL);
}

void *threadfunc(void *dummy) {
	sigset_t sset;
	siginfo_t info;

	sigemptyset(&sset);
	sigaddset(&sset, SIGINT);

	while (1) {
		int sn = sigwaitinfo(&sset, &info);
		printf("%d\n", sn);
		if (sn == -1)
			perror("sigwaitinfo");
	}
}

pthread_t thread;

int StartThread()
{
	return pthread_create(&thread, NULL, &threadfunc, NULL);
}
*/
import "C"

func main() {
	C.StartThread()
	ch := make(chan struct{})
	<-ch
}

What did you expect to see?

Since the doc of os/signal said:

    If the Go program is started with a non-empty signal mask, that will
    generally be honored. However, some signals are explicitly unblocked:
    the synchronous signals, SIGILL, SIGTRAP, SIGSTKFLT, SIGCHLD, SIGPROF,
    and, on GNU/Linux, signals 32 (SIGCANCEL) and 33 (SIGSETXID) (SIGCANCEL
    and SIGSETXID are used internally by glibc).

The program should work: prints 2 for all SIGINTs, even with GDB debugging it.

What did you see instead?

The program exits with status 130. With GDB the stack backtrace is:

#0  syscall () at ../sysdeps/unix/sysv/linux/x86_64/syscall.S:38
#1  0x00007ffff72638ec in runtime.futex (val3=0, addr2=0x0, ts=0x7ffff238ac70, val=0, op=0, addr=0x7ffff7dc1d50 <runtime.sched+176>)
    at ../../../libgo/go/runtime/os_linux.go:17
#2  runtime.futexsleep (val=0, ns=60000000000, addr=0x7ffff7dc1d50 <runtime.sched+176>) at ../../../libgo/go/runtime/os_linux.go:65
#3  runtime.notetsleep_internal (n=0x7ffff7dc1d50 <runtime.sched+176>, ns=60000000000) at ../../../libgo/go/runtime/lock_futex.go:186
#4  0x00007ffff7264974 in runtime.notetsleep (n=n@entry=0x7ffff7dc1d50 <runtime.sched+176>, ns=<optimized out>)
    at ../../../libgo/go/runtime/lock_futex.go:209
#5  0x00007ffff7277637 in runtime.sysmon () at ../../../libgo/go/runtime/proc.go:2157
#6  0x00007ffff6e937a4 in runtime_mstart (mp=<optimized out>) at ../../../libgo/runtime/proc.c:726
#7  0x00007ffff5ba3404 in start_thread (arg=0x7ffff238b700) at pthread_create.c:334
#8  0x00007ffff58e102d in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:109

This suggests a runtime thread has wrong signal mask.

@gopherbot gopherbot added this to the Gccgo milestone Nov 14, 2017
@ianlancetaylor
Copy link
Contributor

Thanks for the report. This is because gccgo 7 included an old version of the Go runtime package--essentially a copy of the Go 1.4 code. This is fixed in the upcoming gccgo version 8. Closing because there are no plans to backport these extensive changes to GCC 7.

@golang golang locked and limited conversation to collaborators Nov 15, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

3 participants