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: "syscall frame is no longer valid" followed by "stack split at bad time" #15639

Closed
liclac opened this issue May 11, 2016 · 5 comments

Comments

Projects
None yet
5 participants
@liclac
Copy link

commented May 11, 2016

I posted this on the golang-nuts mailing list and was told to go here.

There's something strange going on related to cgo-calls that seems to be able to consistently crash the runtime, as demonstrated by this PoC:

$ go get github.com/uppfinnarn/cgocrash
$ cgocrash
runtime: newstack sp=0xc82013ae08 stack=[0xc82013a000, 0xc82013afd0]
    morebuf={pc:0x402aba9 sp:0xc82013ae10 lr:0x0}
    sched={pc:0x402b40d sp:0xc82013ae08 lr:0x0 ctxt:0x0}
gopkg.in/olebedev/go-duktape%2ev2._Cfunc__duk_peval_string(0x5504f50, 0x5413550, 0x1)
    gopkg.in/olebedev/go-duktape.v2/_obj/_cgo_gotypes.go:610 +0x41
gopkg.in/olebedev/go-duktape%2ev2.(*Context).PevalString(0xc82011a000, 0x41e2ec0, 0x7, 0x0, 0x0)
    /Users/uppfinnarn/Projects/Go/src/gopkg.in/olebedev/go-duktape.v2/api.go:879 +0x115
main.main.func1()
    /Users/uppfinnarn/Projects/Go/src/github.com/uppfinnarn/cgocrash/main.go:24 +0x82
created by main.main
    /Users/uppfinnarn/Projects/Go/src/github.com/uppfinnarn/cgocrash/main.go:29 +0x3e
fatal error: runtime: stack split at bad time
# ...lengthy stack trace redacted...

$ go version
go version go1.6.2 darwin/amd64
$ go env
GOARCH="amd64"
GOBIN=""
GOEXE=""
GOHOSTARCH="amd64"
GOHOSTOS="darwin"
GOOS="darwin"
GOPATH="/Users/uppfinnarn/Projects/Go"
GORACE=""
GOROOT="/usr/local/Cellar/go/1.6.2/libexec"
GOTOOLDIR="/usr/local/Cellar/go/1.6.2/libexec/pkg/tool/darwin_amd64"
GO15VENDOREXPERIMENT="1"
CC="clang"
GOGCCFLAGS="-fPIC -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fno-common"
CXX="clang++"
CGO_ENABLED="1"
@ragnarlonn

This comment has been minimized.

Copy link

commented May 11, 2016

I just tried running the PoC on an Ubuntu AWS t2.micro instance to make sure it was not platform-dependent, but I got the same result. See console output below.

ubuntu@ip-172-31-43-85:~/mygo$ uname -a
Linux ip-172-31-43-85 3.13.0-74-generic #118-Ubuntu SMP Thu Dec 17 22:52:10 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux
ubuntu@ip-172-31-43-85:~/mygo$ go version
go version go1.6.2 linux/amd64
ubuntu@ip-172-31-43-85:~/mygo$ go env
GOARCH="amd64"
GOBIN=""
GOEXE=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOOS="linux"
GOPATH="/home/ubuntu/mygo"
GORACE=""
GOROOT="/home/ubuntu/go"
GOTOOLDIR="/home/ubuntu/go/pkg/tool/linux_amd64"
GO15VENDOREXPERIMENT="1"
CC="gcc"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0"
CXX="g++"
CGO_ENABLED="1"

Output from execution:

<ubuntu@ip-172-31-43-85:~/mygo$ bin/cgocrash 
runtime: newstack sp=0xc820035e08 stack=[0xc820035000, 0xc820035fd0]
    morebuf={pc:0x431729 sp:0xc820035e10 lr:0x0}
    sched={pc:0x431f8d sp:0xc820035e08 lr:0x0 ctxt:0x0}
runtime: newstack sp=0xc8204c5e18 stack=[0xc8204c5800, 0xc8204c5fe0]
    morebuf={pc:0x431729 sp:0xc8204c5e20 lr:0x0}
    sched={pc:0x431f8d sp:0xc8204c5e18 lr:0x0 ctxt:0x0}
gopkg.in/olebedev/go-duktape%2ev2._Cfunc__duk_peval_string(0x7f18a0008400, 0x7f18a000e6d0, 0x1)
    gopkg.in/olebedev/go-duktape.v2/_obj/_cgo_gotypes.go:603 +0x41
gopkg.in/olebedev/go-duktape%2ev2.(*Context).PevalString(0xc820024040, 0x5b4708, 0x7, 0x0, 0x0)
    /home/ubuntu/mygo/src/gopkg.in/olebedev/go-duktape.v2/api.go:879 +0x115
main.main.func1()
    /home/ubuntu/mygo/src/github.com/uppfinnarn/cgocrash/main.go:24 +0x82
created by main.main
    /home/ubuntu/mygo/src/github.com/uppfinnarn/cgocrash/main.go:29 +0x3e
fatal error: runtime: stack split at bad time
gopkg.in/olebedev/go-duktape%2ev2._Cfunc__duk_peval_string(0x7f18a8008400, 0x7f18a800e6d0, 0x1)
    gopkg.in/olebedev/go-duktape.v2/_obj/_cgo_gotypes.go:603 +0x41
gopkg.in/olebedev/go-duktape%2ev2.(*Context).PevalString(0xc820024028, 0x5b4708, 0x7, 0x0, 0x0)
    /home/ubuntu/mygo/src/gopkg.in/olebedev/go-duktape.v2/api.go:879 +0x115
main.main.func1()
    /home/ubuntu/mygo/src/github.com/uppfinnarn/cgocrash/main.go:24 +0x82
created by main.main
    /home/ubuntu/mygo/src/github.com/uppfinnarn/cgocrash/main.go:29 +0x3e
fatal error: runtime: stack split at bad time

runtime stack:
runtime.throw(0x5e1ee0, 0x20)
    /home/ubuntu/go/src/runtime/panic.go:547 +0x90
runtime.newstack()
    /home/ubuntu/go/src/runtime/stack.go:834 +0x582
runtime.morestack()
    /home/ubuntu/go/src/runtime/asm_amd64.s:359 +0x7f

goroutine 1810 [syscall, locked to thread]:
runtime.throw(0x5e3220, 0x2d)
    /home/ubuntu/go/src/runtime/panic.go:541 +0x9 fp=0xc8204c5e38 sp=0xc8204c5e20
runtime.exitsyscall(0x0)
    /home/ubuntu/go/src/runtime/proc.go:2419 +0x62 fp=0xc8204c5e60 sp=0xc8204c5e38
runtime.cgocall(0x508ba0, 0xc8204c5ec8, 0x10000c800000000)
    /home/ubuntu/go/src/runtime/cgocall.go:125 +0x147 fp=0xc8204c5e90 sp=0xc8204c5e60
gopkg.in/olebedev/go-duktape%2ev2._Cfunc__duk_peval_string(0x7f18a0008400, 0x7f18a000e6d0, 0x1)
    gopkg.in/olebedev/go-duktape.v2/_obj/_cgo_gotypes.go:603 +0x41 fp=0xc8204c5ec8 sp=0xc8204c5e90
gopkg.in/olebedev/go-duktape%2ev2.(*Context).PevalString(0xc820024040, 0x5b4708, 0x7, 0x0, 0x0)
    /home/ubuntu/mygo/src/gopkg.in/olebedev/go-duktape.v2/api.go:879 +0x115 fp=0xc8204c5f30 sp=0xc8204c5ec8
main.main.func1()
    /home/ubuntu/mygo/src/github.com/uppfinnarn/cgocrash/main.go:24 +0x82 fp=0xc8204c5fc0 sp=0xc8204c5f30
runtime.goexit()
    /home/ubuntu/go/src/runtime/asm_amd64.s:1998 +0x1 fp=0xc8204c5fc8 sp=0xc8204c5fc0
created by main.main
    /home/ubuntu/mygo/src/github.com/uppfinnarn/cgocrash/main.go:29 +0x3e

goroutine 1 [chan receive]:
main.main()
    /home/ubuntu/mygo/src/github.com/uppfinnarn/cgocrash/main.go:35 +0x110

goroutine 17 [syscall, locked to thread]:
runtime.goexit()
    /home/ubuntu/go/src/runtime/asm_amd64.s:1998 +0x1

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

goroutine 6 [runnable]:
main.main.func1()
    /home/ubuntu/mygo/src/github.com/uppfinnarn/cgocrash/main.go:19
created by main.main
    /home/ubuntu/mygo/src/github.com/uppfinnarn/cgocrash/main.go:29 +0x3e>

[...rest of output deleted]

@ianlancetaylor ianlancetaylor changed the title fatal error: runtime: stack split at bad time runtime: "syscall frame is no longer valid" followed by "stack split at bad time" May 11, 2016

@ianlancetaylor ianlancetaylor added this to the Go1.7 milestone May 11, 2016

@bradfitz

This comment has been minimized.

Copy link
Member

commented May 11, 2016

@ianlancetaylor

This comment has been minimized.

Copy link
Contributor

commented May 11, 2016

I did look at go-duktape and did not see any obvious errors. I don't know what is happening here.

@gopherbot

This comment has been minimized.

Copy link

commented May 16, 2016

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

@ianlancetaylor

This comment has been minimized.

Copy link
Contributor

commented May 18, 2016

These problems are happening because the duktape library calls setjmp and longjmp. When calling C code from Go, you can only use setjmp/longjmp within a single C call that does not make any intervening Go calls. Specifically, the call to ctx.RequireNumber is failing and trying to call longjmp to a setjmp that occurred before calling back into Go to invoke func. That can't work. The longjmp is skipping over the intervening Go code.

I think the status right now is that you can use duktape from Go as long as you are careful to not cause any errors. I recommend modifying the duktape code to crash on error rather than calling longjmp.

I'm going to close this issue because I don't think there is anything we can do to fix it.

gopherbot pushed a commit that referenced this issue May 19, 2016

runtime: don't do a plain throw when throwsplit == true
The test case in #15639 somehow causes an invalid syscall frame. The
failure is obscured because the throw occurs when throwsplit == true,
which causes a "stack split at bad time" error when trying to print the
throw message.

This CL fixes the "stack split at bad time" by using systemstack. No
test because there shouldn't be any way to trigger this error anyhow.

Update #15639.

Change-Id: I4240f3fd01bdc3c112f3ffd1316b68504222d9e1
Reviewed-on: https://go-review.googlesource.com/23153
Run-TryBot: Ian Lance Taylor <iant@golang.org>
Reviewed-by: Austin Clements <austin@google.com>

@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.
You can’t perform that action at this time.