go: runtime: fatal error: sweep increased allocation count in go1.7

Please answer these questions before submitting your issue. Thanks!

  1. What version of Go are you using (go version)? go version go1.7 darwin/amd64
  2. What operating system and processor architecture are you using (go env)? GOARCH=“amd64” GOBIN=“” GOEXE=“” GOHOSTARCH=“amd64” GOHOSTOS=“darwin” GOOS=“darwin” GOPATH=“” GORACE=“” GOROOT=“/Users/jeff/go” GOTOOLDIR=“/Users/jeff/go/pkg/tool/darwin_amd64” CC=“clang” GOGCCFLAGS=“-fPIC -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/var/folders/tn/09dglcts0b9gc5111hnf0_dm0000gn/T/go-build421610542=/tmp/go-build -gno-record-gcc-switches -fno-common” CXX=“clang++” CGO_ENABLED=“1”
  3. What did you do? I ran this program: https://play.golang.org/p/LXVU7fsuOr
  4. What did you expect to see? A bunch of pointers forever.
  5. What did you see instead? A bunch of pointers and then
runtime: nelems=512 nfree=510 nalloc=2 previous allocCount=1 nfreed=65535
fatal error: sweep increased allocation count

runtime stack:
runtime.throw(0xa934f, 0x20)
    /Users/jeff/go/src/runtime/panic.go:566 +0x95
runtime.(*mspan).sweep(0x1a42c0, 0x1a4201, 0x2cf01)
    /Users/jeff/go/src/runtime/mgcsweep.go:287 +0x7ab
runtime.(*mcentral).cacheSpan(0xfe450, 0x40002a201)
    /Users/jeff/go/src/runtime/mcentral.go:47 +0x491
runtime.(*mcache).refill(0x12f4b0, 0x2, 0xc420000b60)
    /Users/jeff/go/src/runtime/mcache.go:121 +0xae
runtime.(*mcache).nextFree.func1()
    /Users/jeff/go/src/runtime/malloc.go:505 +0x33
runtime.systemstack(0xc420019500)
    /Users/jeff/go/src/runtime/asm_amd64.s:298 +0x79
runtime.mstart()
    /Users/jeff/go/src/runtime/proc.go:1079

goroutine 1 [running]:
runtime.systemstack_switch()
    /Users/jeff/go/src/runtime/asm_amd64.s:252 fp=0xc42003f900 sp=0xc42003f8f8
runtime.(*mcache).nextFree(0x12f4b0, 0x2, 0x0, 0x0, 0x0)
    /Users/jeff/go/src/runtime/malloc.go:506 +0xb2 fp=0xc42003f958 sp=0xc42003f900
runtime.mallocgc(0x10, 0x0, 0xf300, 0xc42003fa20)
    /Users/jeff/go/src/runtime/malloc.go:658 +0x809 fp=0xc42003f9f8 sp=0xc42003f958
runtime.growslice(0x8b3c0, 0x0, 0x0, 0x0, 0xc, 0xc4203d2010, 0x0, 0x10)
    /Users/jeff/go/src/runtime/slice.go:126 +0x24e fp=0xc42003fa88 sp=0xc42003f9f8
fmt.(*fmt).pad(0xc4203de040, 0xc4203de0a0, 0xc, 0xc)
    /Users/jeff/go/src/fmt/format.go:92 +0x112 fp=0xc42003fb10 sp=0xc42003fa88
fmt.(*fmt).fmt_integer(0xc4203de040, 0xc4203dc010, 0x10, 0x0, 0xa6865, 0x11)
    /Users/jeff/go/src/fmt/format.go:307 +0x1f9 fp=0xc42003fb78 sp=0xc42003fb10
fmt.(*pp).fmt0x64(0xc4203de000, 0xc4203dc010, 0x1)
    /Users/jeff/go/src/fmt/print.go:348 +0x6c fp=0xc42003fbc0 sp=0xc42003fb78
fmt.(*pp).fmtPointer(0xc4203de000, 0x88ea0, 0xc4203dc010, 0x16, 0x70)
    /Users/jeff/go/src/fmt/print.go:515 +0xfc fp=0xc42003fc40 sp=0xc42003fbc0
fmt.(*pp).printArg(0xc4203de000, 0x88ea0, 0xc4203dc010, 0xc400000070)
    /Users/jeff/go/src/fmt/print.go:619 +0xec3 fp=0xc42003fd38 sp=0xc42003fc40
fmt.(*pp).doPrintf(0xc4203de000, 0xa54a5, 0x3, 0xc42003ff28, 0x1, 0x1)
    /Users/jeff/go/src/fmt/print.go:985 +0x123d fp=0xc42003fe20 sp=0xc42003fd38
fmt.Fprintf(0xf6140, 0xc42002c010, 0xa54a5, 0x3, 0xc42003ff28, 0x1, 0x1, 0xd, 0x0, 0x0)
    /Users/jeff/go/src/fmt/print.go:181 +0x76 fp=0xc42003fe88 sp=0xc42003fe20
fmt.Printf(0xa54a5, 0x3, 0xc42003ff28, 0x1, 0x1, 0x10, 0x0, 0x0)
    /Users/jeff/go/src/fmt/print.go:190 +0x72 fp=0xc42003fee8 sp=0xc42003fe88
main.main()
    /Users/jeff/tmp/bolt-bugs/foo.go:17 +0xb8 fp=0xc42003ff48 sp=0xc42003fee8
runtime.main()
    /Users/jeff/go/src/runtime/proc.go:183 +0x1f4 fp=0xc42003ffa0 sp=0xc42003ff48
runtime.goexit()
    /Users/jeff/go/src/runtime/asm_amd64.s:2086 +0x1 fp=0xc42003ffa8 sp=0xc42003ffa0
exit status 2

I’m aware this program is doing something silly by constructing a pointer to a field that isn’t backed by any allocation, but it didn’t crash on go1.6 and I’m not sure if there’s any defined behavior around this. If the answer is “don’t do that then. you’re in wacky land because of unsafe”, that’s fine, I just want to be sure that this isn’t a problem. I found it interesting that it took many prints for it to fail, rather than failing right away.

About this issue

  • Original URL
  • State: closed
  • Created 8 years ago
  • Reactions: 1
  • Comments: 19 (8 by maintainers)

Most upvoted comments

#16772 https://github.com/golang/go/issues/16772 is about pointers causing page faults. The problem here is that there is a pointer to some place in the Go heap where the GC didn’t allocate an object. The GC doesn’t understand what is going on but it knows its internal data structures aren’t fully prepared to deal with such a situation. The difference in between 1.6 and 1.7 is that the 1.7 GC is now smart enough to detect the bug and report that it has found a reference to an object that it didn’t allocate.

Expect the GC to continue to get better at spotting and reporting these kinds of bugs. Think of using unsafe as purchasing technical debt lottery ticket.

On Wed, Aug 17, 2016 at 11:56 PM, Keith Randall notifications@github.com wrote:

Whether they point to Go allocated memory or not is irrelevant. You have always been able (and continue to be able) to have Go pointers point to differently allocated memory (globals, cgo-allocated stuff, syscall.Mmap, etc.). What’s currently newly breaking in go 1.7 is pointer arithmetic on pointers that point to no memory, i.e. faulting pages. I’m thinking about maybe fixing this in some way. See my comment in #16772 https://github.com/golang/go/issues/16772

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/golang/go/issues/16778#issuecomment-240617736, or mute the thread https://github.com/notifications/unsubscribe-auth/AA7Wn2Jw5MyXF3_HWR0QMCZWElJeoPlGks5qg9gKgaJpZM4Jm-NY .

Still reproducible on 4.8.7, but works on vanilla 4.8.10 on Arch Linux thanks a heap !!

However, 4.8.10 doesn’t have CONFIG_USER_NS, building a 4.8.10 with it and will report back if it reproduces

Kudos to @qrwteyrutiyoup for the epic investigation logs 🎸

@qrwteyrutiyoup thanks! I have two ArchLinux boxes with -ck kernel and your comment really brings my a hope=) go compiler and syncthing is broken. I will try to use stock