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 build -gcflags "all=-N -l" runtime.inHeapOrStack: nosplit stack overflow #39323

Closed
GameXG opened this issue May 30, 2020 · 1 comment

Comments

@GameXG
Copy link

GameXG commented May 30, 2020

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

$ go version
go version go1.14.3 linux/amd64

Does this issue reproduce with the latest release?

yes

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

The faulty operating system is the latest version of ubuntu 20.04 (2020-05-30), ubuntu 18.04 does not have this problem

go env Output

ubuntu:~$ go env
GO111MODULE=""
GOARCH="amd64"
GOBIN=""
GOCACHE="/home/aaa/.cache/go-build"
GOENV="/home/aaa/.config/go/env"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOINSECURE=""
GONOPROXY=""
GONOSUMDB=""
GOOS="linux"
GOPATH="/home/aaa/go"
GOPRIVATE=""
GOPROXY="https://goproxy.io"
GOROOT="/usr/local/go"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/usr/local/go/pkg/tool/linux_amd64"
GCCGO="gccgo"
AR="ar"
CC="gcc"
CXX="g++"
CGO_ENABLED="1"
GOMOD=""
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-build022333314=/tmp/go-build -gno-record-gcc-switches"

What did you do?

The faulting code is https://play.golang.org/p/eX7XVgcMFJt

This code is from the google / gvisor project example
https://github.com/google/gvisor/blob/master/pkg/tcpip/sample/tun_tcp_echo/main.go

Need to use this command to get dependent libraries
go get gvisor.dev/gvisor/pkg/tcpip@go

Use the following command to compile
go build -gcflags "all=-N -l"

What did you expect to see?

Compiled successfully

What did you see instead?

aaa@ubuntu:~/go/src/netstack/test1/base1$ go build -gcflags "all=-N -l" /home/aaa/go/src/netstack/test1/base1/base.go
# command-line-arguments
runtime.inHeapOrStack: nosplit stack overflow
        760     assumed on entry to gvisor.dev/gvisor/pkg/abi/linux.(*Statx).CopyOut (nosplit)
        632     after gvisor.dev/gvisor/pkg/abi/linux.(*Statx).CopyOut (nosplit) uses 128
        624     on entry to gvisor.dev/gvisor/pkg/abi/linux.(*Statx).CopyOutN (nosplit)
        336     after gvisor.dev/gvisor/pkg/abi/linux.(*Statx).CopyOutN (nosplit) uses 288
        328     on entry to runtime.gcWriteBarrier (nosplit)
        200     after runtime.gcWriteBarrier (nosplit) uses 128
        192     on entry to runtime.wbBufFlush (nosplit)
        152     after runtime.wbBufFlush (nosplit) uses 40
        144     on entry to runtime.cgoCheckWriteBarrier (nosplit)
        96      after runtime.cgoCheckWriteBarrier (nosplit) uses 48
        88      on entry to runtime.cgoIsGoPointer (nosplit)
        16      after runtime.cgoIsGoPointer (nosplit) uses 72
        8       on entry to runtime.inHeapOrStack (nosplit)
        -24     after runtime.inHeapOrStack (nosplit) uses 32
runtime.morestack: nosplit stack overflow
        760     assumed on entry to gvisor.dev/gvisor/pkg/abi/linux.(*Timespec).CopyOut (nosplit)
        632     after gvisor.dev/gvisor/pkg/abi/linux.(*Timespec).CopyOut (nosplit) uses 128
        624     on entry to gvisor.dev/gvisor/pkg/abi/linux.(*Timespec).CopyOutN (nosplit)
        424     after gvisor.dev/gvisor/pkg/abi/linux.(*Timespec).CopyOutN (nosplit) uses 200
        416     on entry to runtime.gcWriteBarrier (nosplit)
        288     after runtime.gcWriteBarrier (nosplit) uses 128
        280     on entry to runtime.wbBufFlush (nosplit)
        240     after runtime.wbBufFlush (nosplit) uses 40
        232     on entry to runtime.cgoCheckWriteBarrier (nosplit)
        184     after runtime.cgoCheckWriteBarrier (nosplit) uses 48
        176     on entry to runtime.cgoIsGoPointer (nosplit)
        104     after runtime.cgoIsGoPointer (nosplit) uses 72
        96      on entry to runtime.inHeapOrStack (nosplit)
        64      after runtime.inHeapOrStack (nosplit) uses 32
        56      on entry to runtime.spanOf (nosplit)
        16      after runtime.spanOf (nosplit) uses 40
        8       on entry to runtime.panicIndexU (nosplit)
        0       on entry to runtime.goPanicIndexU
        -8      on entry to runtime.morestack (nosplit)
runtime.morestack: nosplit stack overflow
        760     assumed on entry to gvisor.dev/gvisor/pkg/abi/linux.(*StatxTimestamp).CopyOut (nosplit)
        632     after gvisor.dev/gvisor/pkg/abi/linux.(*StatxTimestamp).CopyOut (nosplit) uses 128
        624     on entry to gvisor.dev/gvisor/pkg/abi/linux.(*StatxTimestamp).CopyOutN (nosplit)
        424     after gvisor.dev/gvisor/pkg/abi/linux.(*StatxTimestamp).CopyOutN (nosplit) uses 200
        416     on entry to runtime.gcWriteBarrier (nosplit)
        288     after runtime.gcWriteBarrier (nosplit) uses 128
        280     on entry to runtime.wbBufFlush (nosplit)
        240     after runtime.wbBufFlush (nosplit) uses 40
        232     on entry to runtime.cgoCheckWriteBarrier (nosplit)
        184     after runtime.cgoCheckWriteBarrier (nosplit) uses 48
        176     on entry to runtime.cgoIsGoPointer (nosplit)
        104     after runtime.cgoIsGoPointer (nosplit) uses 72
        96      on entry to runtime.inHeapOrStack (nosplit)
        64      after runtime.inHeapOrStack (nosplit) uses 32
        56      on entry to runtime.spanOf (nosplit)
        16      after runtime.spanOf (nosplit) uses 40
        8       on entry to runtime.panicIndexU (nosplit)
        0       on entry to runtime.goPanicIndexU
        -8      on entry to runtime.morestack (nosplit)
runtime.morestack: nosplit stack overflow
        760     assumed on entry to gvisor.dev/gvisor/pkg/abi/linux.(*EpollEvent).CopyOut (nosplit)
        632     after gvisor.dev/gvisor/pkg/abi/linux.(*EpollEvent).CopyOut (nosplit) uses 128
        624     on entry to gvisor.dev/gvisor/pkg/abi/linux.(*EpollEvent).CopyOutN (nosplit)
        424     after gvisor.dev/gvisor/pkg/abi/linux.(*EpollEvent).CopyOutN (nosplit) uses 200
        416     on entry to runtime.gcWriteBarrier (nosplit)
        288     after runtime.gcWriteBarrier (nosplit) uses 128
        280     on entry to runtime.wbBufFlush (nosplit)
        240     after runtime.wbBufFlush (nosplit) uses 40
        232     on entry to runtime.cgoCheckWriteBarrier (nosplit)
        184     after runtime.cgoCheckWriteBarrier (nosplit) uses 48
        176     on entry to runtime.cgoIsGoPointer (nosplit)
        104     after runtime.cgoIsGoPointer (nosplit) uses 72
        96      on entry to runtime.inHeapOrStack (nosplit)
        64      after runtime.inHeapOrStack (nosplit) uses 32
        56      on entry to runtime.spanOf (nosplit)
        16      after runtime.spanOf (nosplit) uses 40
        8       on entry to runtime.panicIndexU (nosplit)
        0       on entry to runtime.goPanicIndexU
        -8      on entry to runtime.morestack (nosplit)
runtime.inHeapOrStack: nosplit stack overflow
        760     assumed on entry to gvisor.dev/gvisor/pkg/abi/linux.(*Stat).CopyOut (nosplit)
        632     after gvisor.dev/gvisor/pkg/abi/linux.(*Stat).CopyOut (nosplit) uses 128
        624     on entry to gvisor.dev/gvisor/pkg/abi/linux.(*Stat).CopyOutN (nosplit)
        344     after gvisor.dev/gvisor/pkg/abi/linux.(*Stat).CopyOutN (nosplit) uses 280
        336     on entry to runtime.gcWriteBarrier (nosplit)
        208     after runtime.gcWriteBarrier (nosplit) uses 128
        200     on entry to runtime.wbBufFlush (nosplit)
        160     after runtime.wbBufFlush (nosplit) uses 40
        152     on entry to runtime.cgoCheckWriteBarrier (nosplit)
        104     after runtime.cgoCheckWriteBarrier (nosplit) uses 48
        96      on entry to runtime.cgoIsGoPointer (nosplit)
        24      after runtime.cgoIsGoPointer (nosplit) uses 72
        16      on entry to runtime.inHeapOrStack (nosplit)
        -16     after runtime.inHeapOrStack (nosplit) uses 32
runtime.morestack: nosplit stack overflow
        760     assumed on entry to gvisor.dev/gvisor/pkg/abi/linux.(*PtraceRegs).CopyOut (nosplit)
        632     after gvisor.dev/gvisor/pkg/abi/linux.(*PtraceRegs).CopyOut (nosplit) uses 128
        624     on entry to gvisor.dev/gvisor/pkg/abi/linux.(*PtraceRegs).CopyOutN (nosplit)
        424     after gvisor.dev/gvisor/pkg/abi/linux.(*PtraceRegs).CopyOutN (nosplit) uses 200
        416     on entry to runtime.gcWriteBarrier (nosplit)
        288     after runtime.gcWriteBarrier (nosplit) uses 128
        280     on entry to runtime.wbBufFlush (nosplit)
        240     after runtime.wbBufFlush (nosplit) uses 40
        232     on entry to runtime.cgoCheckWriteBarrier (nosplit)
        184     after runtime.cgoCheckWriteBarrier (nosplit) uses 48
        176     on entry to runtime.cgoIsGoPointer (nosplit)
        104     after runtime.cgoIsGoPointer (nosplit) uses 72
        96      on entry to runtime.inHeapOrStack (nosplit)
        64      after runtime.inHeapOrStack (nosplit) uses 32
        56      on entry to runtime.spanOf (nosplit)
        16      after runtime.spanOf (nosplit) uses 40
        8       on entry to runtime.panicIndexU (nosplit)
        0       on entry to runtime.goPanicIndexU
        -8      on entry to runtime.morestack (nosplit)
@ianlancetaylor ianlancetaylor changed the title go build -gcflags "all=-N -l" runtime.inHeapOrStack: nosplit stack overflow runtime: go build -gcflags "all=-N -l" runtime.inHeapOrStack: nosplit stack overflow May 30, 2020
@ianlancetaylor
Copy link
Contributor

I don't think there is much that we can do here. The failure is occurring because some code in gvisor.dev/gvisor/pkg/abi/linux is marked nosplit. I guess that is working for normal compilation, but when you disable optimizations and inlining the code takes up too much stack space.

The only fix for this is for the nosplit code to use less stack space when not optimizing. It looks like the biggest culprit is

gvisor.dev/gvisor/pkg/abi/linux.(*Statx).CopyOutN (nosplit) uses 288

In order for this to work that function, and perhaps others, will need to be simplified. Or not marked as nosplit, but presumably there is a good reason for it to be nosplit. But that function is not part of the Go project, so there isn't anything that the Go project can do about it.

So I'm going to close this issue since I don't see any action that we can take. Please comment if you disagree.

@golang golang locked and limited conversation to collaborators May 30, 2021
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