golang / go

The Go programming language
https://go.dev
BSD 3-Clause "New" or "Revised" License
124.14k stars 17.69k forks source link

runtime: go build -gcflags "all=-N -l" runtime.inHeapOrStack: nosplit stack overflow #39323

Closed ghost closed 4 years ago

ghost commented 4 years ago

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 commented 4 years ago

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.