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: Go runtime fails to panic when sent SIGSYS #15204

Closed
flowerhack opened this issue Apr 8, 2016 · 10 comments
Closed

runtime: Go runtime fails to panic when sent SIGSYS #15204

flowerhack opened this issue Apr 8, 2016 · 10 comments
Milestone

Comments

@flowerhack
Copy link
Contributor

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

go version go1.6 linux/amd64

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

GOARCH="amd64"
GOBIN=""
GOEXE=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOOS="linux"
GOPATH=""
GORACE=""
GOROOT="/usr/lib/google-golang"
GOTOOLDIR="/usr/lib/google-golang/pkg/tool/linux_amd64"
GO15VENDOREXPERIMENT="1"
CC="gcc"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -gno-record-gcc-switches -fdebug-prefix-map=/tmp/go-build195194165=/tmp/go-build"
CXX="g++"
CGO_ENABLED="1"

3. What did you do?
I sent a SIGSYS signal to a Go program.

Program: https://gist.github.com/flowerhack/b0a46e5fabeb3d9c214e14543e67fe50

(Unfortunately, I can't include a play.golang.org link, since the playground doesn't seem to recognize some important parts of the syscall package, e.g. syscall.SIGSYS.)

4. What did you expect to see?

I expected to see the program exit with a stack dump. (Documentation that states this should occur: https://golang.org/pkg/os/signal/).

5. What did you see instead?

The program continued to run.

(I have a patch for this issue that I'll be submitting shortly~)

@mikioh mikioh changed the title Go runtime fails to panic when sent SIGSYS runtime: Go runtime fails to panic when sent SIGSYS Apr 9, 2016
@mikioh
Copy link
Contributor

mikioh commented Apr 9, 2016

/CC @ianlancetaylor

The runtime never throws SIGSYS but instead notifies it to the user program on some platforms. It's a easy way to make a simple syscall fallback mechanism; try an old system call when a newer system call fails. At least the net package depends on the behavior, perhaps the os package too.

@ianlancetaylor ianlancetaylor added this to the Go1.7 milestone Apr 9, 2016
@ianlancetaylor
Copy link
Member

It looks like right now we crash with a stack trace for SIGSYS on Darwin, DragonFly, NetBSD, OpenBSD, and Solaris. We do not crash on FreeBSD and GNU/Linux. As far as I can tell, the different behaviour on GNU/Linux was accidentally introduced in https://golang.org/cl/3749041 .

I think we should undo that change, and make SIGSYS crash with a stack trace on all platforms. The net package does not depend on any particular SIGSYS behaviour. It depends on an invalid system call returning ENOSYS, which it will regardless of how SIGSYS is handled. There are very few cases in which the Linux kernel will send a SIGSYS signal.

@mikioh
Copy link
Contributor

mikioh commented Apr 9, 2016

It depends on an invalid system call returning ENOSYS, which it will regardless of how SIGSYS is handled.

Thanks for the correction, ENOSYS or EINVAL though.

There are very few cases in which the Linux kernel will send a SIGSYS signal.

Do you have any good idea for fixing FreeBSD? I guess that vanilla FreeBSD kernels throw SIGSYS when they face unknown system calls by default. Are you in favor of introducing FreeBSD kernel version identification? (Or dropping support for FreeBSD 9 and below?)

@ianlancetaylor
Copy link
Member

I don't know enough about FreeBSD. I gather that on FreeBSD if you call an unimplemented system call it sends a SIGSYS signal? What happens if SIGSYS is blocked or ignored?

In any case I'm fine with checking kernel versions on FreeBSD if appropriate. Or, according to https://github.com/golang/go/wiki/FreeBSD we currently don't support anything before FreeBSD 8; it would probably be OK to not support anything before FreeBSD 9.

@flowerhack
Copy link
Contributor Author

Patch for this issue here: https://go-review.googlesource.com/#/c/22202/ Comments/thoughts/etc welcome!

@gopherbot
Copy link
Contributor

CL https://golang.org/cl/22202 mentions this issue.

gopherbot pushed a commit that referenced this issue Apr 19, 2016
On GNU/Linux, SIGSYS is specified to cause the process to terminate
without a core dump. In https://codereview.appspot.com/3749041 , it
appears that Golang accidentally introduced incorrect behavior for
this signal, which caused Golang processes to keep running after
receiving SIGSYS. This change reverts it to the old/correct behavior.

Updates #15204

Change-Id: I3aa48a9499c1bc36fa5d3f40c088fdd7599e0db5
Reviewed-on: https://go-review.googlesource.com/22202
Reviewed-by: Ian Lance Taylor <iant@golang.org>
@mikioh
Copy link
Contributor

mikioh commented Apr 27, 2016

When we set SIGSYS to _SigThrow + _SigUnblock in runtime/signal_freebsd.go, the following snippet crashes.

package main

import (
        "os/signal"
        "syscall"
)

func main() {
        signal.Ignore(syscall.SIGSYS)
        if _, _, errno := syscall.Syscall6(5682, 0, 0, 0, 0, 0, 0); errno != 0 {
                println(error(errno).Error())
        }
}
# go run syscall.go
SIGSYS: bad system call
PC=0x44e17a m=0

goroutine 1 [syscall]:
syscall.Syscall6(0x1632, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x443b90, 0x0, 0x0)
    /go/src/syscall/asm_freebsd_amd64.s:44 +0x5 fp=0xc820035ec0 sp=0xc820035eb8
main.main()
    /syscall.go:10 +0xe4 fp=0xc820035f50 sp=0xc820035ec0
runtime.main()
    /go/src/runtime/proc.go:188 +0x20a fp=0xc820035fa0 sp=0xc820035f50
runtime.goexit()
    /home/mikioh/go/src/runtime/asm_amd64.s:2054 +0x1 fp=0xc820035fa8 sp=0xc820035fa0

goroutine 5 [runnable]:
os/signal.loop()
    /go/src/os/signal/signal_unix.go:20
created by os/signal.init.1
    /go/src/os/signal/signal_unix.go:28 +0x37
(snip)

See https://github.com/freebsd/freebsd/blob/master/sys/kern/kern_sig.c#L3440.

@ianlancetaylor
Copy link
Member

It sounds like SIGSYS is handled as we expect on every system other than FreeBSD, and on FreeBSD there is nothing we can reasonably do. Seems to me we should just close this issue at this point.

@gopherbot
Copy link
Contributor

CL https://golang.org/cl/22537 mentions this issue.

gopherbot pushed a commit that referenced this issue Apr 28, 2016
The _SigUnblock flag was appended to SIGSYS slot of runtime signal table
for Linux in https://go-review.googlesource.com/22202, but there is
still no concrete opinion on whether SIGSYS must be an unblocked signal
for runtime.

This change removes _SigUnblock flag from SIGSYS on Linux for
consistency in runtime signal handling and adds a reference to #15204 to
runtime signal table for FreeBSD.

Updates #15204.

Change-Id: I42992b1d852c2ab5dd37d6dbb481dba46929f665
Reviewed-on: https://go-review.googlesource.com/22537
Reviewed-by: Ian Lance Taylor <iant@golang.org>
@rsc
Copy link
Contributor

rsc commented May 18, 2016

Per Ian's last comment, seems like we're done.

@rsc rsc closed this as completed May 18, 2016
@golang golang locked and limited conversation to collaborators May 18, 2017
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

5 participants