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

cmd/compile: value assigned to global fails to escape #29000

Closed
zeldovich opened this issue Nov 29, 2018 · 23 comments
Closed

cmd/compile: value assigned to global fails to escape #29000

zeldovich opened this issue Nov 29, 2018 · 23 comments
Labels
FrozenDueToAge NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. release-blocker
Milestone

Comments

@zeldovich
Copy link

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

$ go version
go version go1.11.2 linux/amd64

Does this issue reproduce with the latest release?

Yes.

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

go env Output
$ go env
GOARCH="amd64"
GOBIN=""
GOCACHE="/home/nickolai/.cache/go-build"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOOS="linux"
GOPATH="/home/nickolai/go"
GOPROXY=""
GORACE=""
GOROOT="/usr/local/go-1.11.2"
GOTMPDIR=""
GOTOOLDIR="/usr/local/go-1.11.2/pkg/tool/linux_amd64"
GCCGO="gccgo"
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-build999639115=/tmp/go-build -gno-record-gcc-switches"

What did you do?

$ cat bug_test.go
package bug

import (
	"fmt"
	_ "net"
	"testing"
)

type A struct {
	buf [32]byte
}

type Z struct {
	buf [256]byte
}

var saved interface{}

func (a A) f(x interface{}) {
	switch x := x.(type) {
	case Z:
		a.g(x)
	}
}

func (a A) g(z Z) {
	a.h(a, z)
}

func (a A) h(_ A, x interface{}) {
	fmt.Printf("h\n")

	saved = x
	return

	a.f(x)
}

func w(i interface{}) {
}

func TestBug(t *testing.T) {
	big := make([]byte, 1024, 1024)
	big[0] = 1

	var z Z
	z.buf[0] = 1

	var a A
	a.f(z)

	m := make(map[int]int)
	for i := 0; i < 1000000; i++ {
		m[i] = i
	}
}
$ GOGC=1 go test . -v -count=1
=== RUN   TestBug
h
runtime: pointer 0xc0000bf640 to unallocated span span.base()=0xc0000b8000 span.limit=0xc0000c0000 span.state=3
runtime: found in object at *(0x630540+0x278)
object=0x630540 s=nil
fatal error: found bad pointer in Go heap (incorrect use of unsafe or cgo?)

runtime stack:
runtime.throw(0x547f29, 0x3e)
	/usr/local/go-1.11.2/src/runtime/panic.go:608 +0x72 fp=0x7fa12c91bc88 sp=0x7fa12c91bc58 pc=0x42ac12
runtime.findObject(0xc0000bf640, 0x630540, 0x278, 0x7fa130b09560, 0xc00002b770, 0xc)
	/usr/local/go-1.11.2/src/runtime/mbitmap.go:399 +0x3b6 fp=0x7fa12c91bcd8 sp=0x7fa12c91bc88 pc=0x412ed6
runtime.scanblock(0x630540, 0x1ce10, 0x7fa130b119e3, 0xc00002b770)
	/usr/local/go-1.11.2/src/runtime/mgcmark.go:1048 +0xa9 fp=0x7fa12c91bd30 sp=0x7fa12c91bcd8 pc=0x41dad9
runtime.markrootBlock(0x630540, 0x1ce10, 0x7fa130b119e3, 0xc00002b770, 0x0)
	/usr/local/go-1.11.2/src/runtime/mgcmark.go:294 +0x90 fp=0x7fa12c91bd60 sp=0x7fa12c91bd30 pc=0x41c0c0
runtime.markroot(0xc00002b770, 0xc000000003)
	/usr/local/go-1.11.2/src/runtime/mgcmark.go:200 +0x1a9 fp=0x7fa12c91bde0 sp=0x7fa12c91bd60 pc=0x41be69
runtime.gcDrain(0xc00002b770, 0x5)
	/usr/local/go-1.11.2/src/runtime/mgcmark.go:882 +0x117 fp=0x7fa12c91be38 sp=0x7fa12c91bde0 pc=0x41d4c7
runtime.gcBgMarkWorker.func2()
	/usr/local/go-1.11.2/src/runtime/mgc.go:1839 +0x80 fp=0x7fa12c91be78 sp=0x7fa12c91be38 pc=0x453cb0
runtime.systemstack(0x0)
	/usr/local/go-1.11.2/src/runtime/asm_amd64.s:351 +0x66 fp=0x7fa12c91be80 sp=0x7fa12c91be78 pc=0x455fb6
runtime.mstart()
	/usr/local/go-1.11.2/src/runtime/proc.go:1229 fp=0x7fa12c91be88 sp=0x7fa12c91be80 pc=0x42f4e0

goroutine 34 [GC worker (idle)]:
runtime.systemstack_switch()
	/usr/local/go-1.11.2/src/runtime/asm_amd64.s:311 fp=0xc000396760 sp=0xc000396758 pc=0x455f40
runtime.gcBgMarkWorker(0xc00002a500)
	/usr/local/go-1.11.2/src/runtime/mgc.go:1826 +0x1b8 fp=0xc0003967d8 sp=0xc000396760 pc=0x41a248
runtime.goexit()
	/usr/local/go-1.11.2/src/runtime/asm_amd64.s:1333 +0x1 fp=0xc0003967e0 sp=0xc0003967d8 pc=0x458021
created by runtime.gcBgMarkStartWorkers
	/usr/local/go-1.11.2/src/runtime/mgc.go:1720 +0x77

goroutine 1 [chan receive]:
runtime.gopark(0x548918, 0xc000088298, 0x170d, 0x3)
	/usr/local/go-1.11.2/src/runtime/proc.go:302 +0xeb fp=0xc00005bb58 sp=0xc00005bb38 pc=0x42c97b
runtime.goparkunlock(0xc000088298, 0x170d, 0x3)
	/usr/local/go-1.11.2/src/runtime/proc.go:308 +0x53 fp=0xc00005bb88 sp=0xc00005bb58 pc=0x42ca23
runtime.chanrecv(0xc000088240, 0xc0000bdc9f, 0xc000000301, 0x4b3573)
	/usr/local/go-1.11.2/src/runtime/chan.go:520 +0x2be fp=0xc00005bc18 sp=0xc00005bb88 pc=0x4064ae
runtime.chanrecv1(0xc000088240, 0xc0000bdc9f)
	/usr/local/go-1.11.2/src/runtime/chan.go:402 +0x2b fp=0xc00005bc48 sp=0xc00005bc18 pc=0x4061db
testing.(*T).Run(0xc0000e2100, 0x53f83c, 0x7, 0x5484e8, 0x469a46)
	/usr/local/go-1.11.2/src/testing/testing.go:879 +0x37a fp=0xc00005bd00 sp=0xc00005bc48 pc=0x4b359a
testing.runTests.func1(0xc0000e2000)
	/usr/local/go-1.11.2/src/testing/testing.go:1119 +0x78 fp=0xc00005bd50 sp=0xc00005bd00 pc=0x4b7268
testing.tRunner(0xc0000e2000, 0xc0000bde08)
	/usr/local/go-1.11.2/src/testing/testing.go:827 +0xbf fp=0xc00005bd78 sp=0xc00005bd50 pc=0x4b31bf
testing.runTests(0xc0000ac060, 0x6296e0, 0x1, 0x1, 0x40c09f)
	/usr/local/go-1.11.2/src/testing/testing.go:1117 +0x2aa fp=0xc00005be38 sp=0xc00005bd78 pc=0x4b4a4a
testing.(*M).Run(0xc0000e0000, 0x0)
	/usr/local/go-1.11.2/src/testing/testing.go:1034 +0x165 fp=0xc00005bf30 sp=0xc00005be38 pc=0x4b3995
main.main()
	_testmain.go:42 +0x13d fp=0xc00005bf98 sp=0xc00005bf30 pc=0x4f529d
runtime.main()
	/usr/local/go-1.11.2/src/runtime/proc.go:201 +0x207 fp=0xc00005bfe0 sp=0xc00005bf98 pc=0x42c587
runtime.goexit()
	/usr/local/go-1.11.2/src/runtime/asm_amd64.s:1333 +0x1 fp=0xc00005bfe8 sp=0xc00005bfe0 pc=0x458021

goroutine 2 [force gc (idle)]:
runtime.gopark(0x548918, 0x630f70, 0x1410, 0x1)
	/usr/local/go-1.11.2/src/runtime/proc.go:302 +0xeb fp=0xc000048f80 sp=0xc000048f60 pc=0x42c97b
runtime.goparkunlock(0x630f70, 0x1410, 0x1)
	/usr/local/go-1.11.2/src/runtime/proc.go:308 +0x53 fp=0xc000048fb0 sp=0xc000048f80 pc=0x42ca23
runtime.forcegchelper()
	/usr/local/go-1.11.2/src/runtime/proc.go:251 +0xb3 fp=0xc000048fe0 sp=0xc000048fb0 pc=0x42c7f3
runtime.goexit()
	/usr/local/go-1.11.2/src/runtime/asm_amd64.s:1333 +0x1 fp=0xc000048fe8 sp=0xc000048fe0 pc=0x458021
created by runtime.init.4
	/usr/local/go-1.11.2/src/runtime/proc.go:240 +0x35

goroutine 3 [GC sweep wait]:
runtime.gopark(0x548918, 0x6310e0, 0x45140c, 0x1)
	/usr/local/go-1.11.2/src/runtime/proc.go:302 +0xeb fp=0xc000049780 sp=0xc000049760 pc=0x42c97b
runtime.goparkunlock(0x6310e0, 0x55140c, 0x1)
	/usr/local/go-1.11.2/src/runtime/proc.go:308 +0x53 fp=0xc0000497b0 sp=0xc000049780 pc=0x42ca23
runtime.bgsweep(0xc000020070)
	/usr/local/go-1.11.2/src/runtime/mgcsweep.go:71 +0x102 fp=0xc0000497d8 sp=0xc0000497b0 pc=0x41ef52
runtime.goexit()
	/usr/local/go-1.11.2/src/runtime/asm_amd64.s:1333 +0x1 fp=0xc0000497e0 sp=0xc0000497d8 pc=0x458021
created by runtime.gcenable
	/usr/local/go-1.11.2/src/runtime/mgc.go:216 +0x58

goroutine 18 [finalizer wait]:
runtime.gopark(0x548918, 0x64d460, 0x140f, 0x1)
	/usr/local/go-1.11.2/src/runtime/proc.go:302 +0xeb fp=0xc000044728 sp=0xc000044708 pc=0x42c97b
runtime.goparkunlock(0x64d460, 0x140f, 0x1)
	/usr/local/go-1.11.2/src/runtime/proc.go:308 +0x53 fp=0xc000044758 sp=0xc000044728 pc=0x42ca23
runtime.runfinq()
	/usr/local/go-1.11.2/src/runtime/mfinal.go:175 +0x99 fp=0xc0000447e0 sp=0xc000044758 pc=0x4168b9
runtime.goexit()
	/usr/local/go-1.11.2/src/runtime/asm_amd64.s:1333 +0x1 fp=0xc0000447e8 sp=0xc0000447e0 pc=0x458021
created by runtime.createfing
	/usr/local/go-1.11.2/src/runtime/mfinal.go:156 +0x61

goroutine 19 [runnable]:
runtime.advanceEvacuationMark(0xc000056f68, 0x516840, 0x1000)
	/usr/local/go-1.11.2/src/runtime/map.go:1178 +0xd6 fp=0xc000056a70 sp=0xc000056a68 pc=0x40f546
runtime.evacuate_fast64(0x516840, 0xc000056f68, 0x562)
	/usr/local/go-1.11.2/src/runtime/map_fast64.go:417 +0x3f3 fp=0xc000056b18 sp=0xc000056a70 pc=0x4110a3
runtime.growWork_fast64(0x516840, 0xc000056f68, 0x14d4)
	/usr/local/go-1.11.2/src/runtime/map_fast64.go:321 +0x93 fp=0xc000056b40 sp=0xc000056b18 pc=0x410c93
runtime.mapassign_fast64(0x516840, 0xc000056f68, 0x6c9b, 0xc0002f3f70)
	/usr/local/go-1.11.2/src/runtime/map_fast64.go:115 +0x272 fp=0xc000056b80 sp=0xc000056b40 pc=0x4107e2
_/home/nickolai/tmp/gobug2.TestBug(0xc0000e2100)
	/home/nickolai/tmp/gobug2/bug_test.go:54 +0x157 fp=0xc000056fa8 sp=0xc000056b80 pc=0x4f5057
testing.tRunner(0xc0000e2100, 0x5484e8)
	/usr/local/go-1.11.2/src/testing/testing.go:827 +0xbf fp=0xc000056fd0 sp=0xc000056fa8 pc=0x4b31bf
runtime.goexit()
	/usr/local/go-1.11.2/src/runtime/asm_amd64.s:1333 +0x1 fp=0xc000056fd8 sp=0xc000056fd0 pc=0x458021
created by testing.(*T).Run
	/usr/local/go-1.11.2/src/testing/testing.go:878 +0x353

goroutine 20 [GC worker (idle)]:
runtime.gopark(0x5487e0, 0xc0000140e0, 0xc000041417, 0x0)
	/usr/local/go-1.11.2/src/runtime/proc.go:302 +0xeb fp=0xc000048760 sp=0xc000048740 pc=0x42c97b
runtime.gcBgMarkWorker(0xc000028000)
	/usr/local/go-1.11.2/src/runtime/mgc.go:1772 +0xfc fp=0xc0000487d8 sp=0xc000048760 pc=0x41a18c
runtime.goexit()
	/usr/local/go-1.11.2/src/runtime/asm_amd64.s:1333 +0x1 fp=0xc0000487e0 sp=0xc0000487d8 pc=0x458021
created by runtime.gcBgMarkStartWorkers
	/usr/local/go-1.11.2/src/runtime/mgc.go:1720 +0x77

goroutine 4 [GC worker (idle)]:
runtime.gopark(0x5487e0, 0xc00009e2a0, 0x1417, 0x0)
	/usr/local/go-1.11.2/src/runtime/proc.go:302 +0xeb fp=0xc000049f60 sp=0xc000049f40 pc=0x42c97b
runtime.gcBgMarkWorker(0xc00002ca00)
	/usr/local/go-1.11.2/src/runtime/mgc.go:1772 +0xfc fp=0xc000049fd8 sp=0xc000049f60 pc=0x41a18c
runtime.goexit()
	/usr/local/go-1.11.2/src/runtime/asm_amd64.s:1333 +0x1 fp=0xc000049fe0 sp=0xc000049fd8 pc=0x458021
created by runtime.gcBgMarkStartWorkers
	/usr/local/go-1.11.2/src/runtime/mgc.go:1720 +0x77

goroutine 35 [GC worker (idle)]:
runtime.gopark(0x5487e0, 0xc00039c000, 0x1417, 0x0)
	/usr/local/go-1.11.2/src/runtime/proc.go:302 +0xeb fp=0xc000396f60 sp=0xc000396f40 pc=0x42c97b
runtime.gcBgMarkWorker(0xc00002ef00)
	/usr/local/go-1.11.2/src/runtime/mgc.go:1772 +0xfc fp=0xc000396fd8 sp=0xc000396f60 pc=0x41a18c
runtime.goexit()
	/usr/local/go-1.11.2/src/runtime/asm_amd64.s:1333 +0x1 fp=0xc000396fe0 sp=0xc000396fd8 pc=0x458021
created by runtime.gcBgMarkStartWorkers
	/usr/local/go-1.11.2/src/runtime/mgc.go:1720 +0x77

goroutine 36 [GC worker (idle)]:
runtime.gopark(0x5487e0, 0xc00009e2b0, 0x1417, 0x0)
	/usr/local/go-1.11.2/src/runtime/proc.go:302 +0xeb fp=0xc000397760 sp=0xc000397740 pc=0x42c97b
runtime.gcBgMarkWorker(0xc000031400)
	/usr/local/go-1.11.2/src/runtime/mgc.go:1772 +0xfc fp=0xc0003977d8 sp=0xc000397760 pc=0x41a18c
runtime.goexit()
	/usr/local/go-1.11.2/src/runtime/asm_amd64.s:1333 +0x1 fp=0xc0003977e0 sp=0xc0003977d8 pc=0x458021
created by runtime.gcBgMarkStartWorkers
	/usr/local/go-1.11.2/src/runtime/mgc.go:1720 +0x77

goroutine 21 [GC worker (idle)]:
runtime.gopark(0x5487e0, 0xc000014100, 0x1417, 0x0)
	/usr/local/go-1.11.2/src/runtime/proc.go:302 +0xeb fp=0xc000044f60 sp=0xc000044f40 pc=0x42c97b
runtime.gcBgMarkWorker(0xc000033900)
	/usr/local/go-1.11.2/src/runtime/mgc.go:1772 +0xfc fp=0xc000044fd8 sp=0xc000044f60 pc=0x41a18c
runtime.goexit()
	/usr/local/go-1.11.2/src/runtime/asm_amd64.s:1333 +0x1 fp=0xc000044fe0 sp=0xc000044fd8 pc=0x458021
created by runtime.gcBgMarkStartWorkers
	/usr/local/go-1.11.2/src/runtime/mgc.go:1720 +0x77

goroutine 37 [GC worker (idle)]:
runtime.gopark(0x5487e0, 0xc00039c010, 0x1417, 0x0)
	/usr/local/go-1.11.2/src/runtime/proc.go:302 +0xeb fp=0xc000397f60 sp=0xc000397f40 pc=0x42c97b
runtime.gcBgMarkWorker(0xc000036000)
	/usr/local/go-1.11.2/src/runtime/mgc.go:1772 +0xfc fp=0xc000397fd8 sp=0xc000397f60 pc=0x41a18c
runtime.goexit()
	/usr/local/go-1.11.2/src/runtime/asm_amd64.s:1333 +0x1 fp=0xc000397fe0 sp=0xc000397fd8 pc=0x458021
created by runtime.gcBgMarkStartWorkers
	/usr/local/go-1.11.2/src/runtime/mgc.go:1720 +0x77

goroutine 38 [GC worker (idle)]:
runtime.gopark(0x5487e0, 0xc000014110, 0x1417, 0x0)
	/usr/local/go-1.11.2/src/runtime/proc.go:302 +0xeb fp=0xc000398760 sp=0xc000398740 pc=0x42c97b
runtime.gcBgMarkWorker(0xc000038500)
	/usr/local/go-1.11.2/src/runtime/mgc.go:1772 +0xfc fp=0xc0003987d8 sp=0xc000398760 pc=0x41a18c
runtime.goexit()
	/usr/local/go-1.11.2/src/runtime/asm_amd64.s:1333 +0x1 fp=0xc0003987e0 sp=0xc0003987d8 pc=0x458021
created by runtime.gcBgMarkStartWorkers
	/usr/local/go-1.11.2/src/runtime/mgc.go:1720 +0x77
FAIL	_/home/nickolai/tmp/gobug2	0.018s
$ 

What did you expect to see?

No symptoms of runtime memory corruption.

What did you see instead?

Symptoms of runtime memory corruption.

@mark-rushakoff
Copy link
Contributor

I can confirm the failure on go1.11.2, but I can't repro it with tip (go version devel +96d41786c5 Wed Nov 28 18:53:53 2018 +0000 darwin/amd64). Running with GOGC=1 seems relevant, because it passes for me when GOGC isn't overridden.

Here's a very slightly reduced test case (removed unneeded import, uncalled function) with a couple comments added about crash behavior when removing other lines:

package bug

import (
	"fmt"
	"testing"
)

type A struct {
	buf [32]byte
}

type Z struct {
	buf [256]byte
}

var saved interface{}

func (a A) f(x interface{}) {
	switch x := x.(type) {
	case Z:
		a.g(x)
	}
}

func (a A) g(z Z) {
	a.h(a, z)
}

func (a A) h(_ A, x interface{}) {
	fmt.Printf("h\n") // Commenting out just this line causes the test to pass.

	saved = x
	return

	a.f(x) // Commentint out just this line causes the test to pass.
}

func TestBug(t *testing.T) {
	big := make([]byte, 1024, 1024)
	big[0] = 1

	var z Z
	z.buf[0] = 1

	var a A
	a.f(z)

	m := make(map[int]int)
	for i := 0; i < 1000000; i++ {
		m[i] = i
	}
}

@zeldovich
Copy link
Author

Here's another version of the bug-triggering code that's better in two important ways:

  • It much more reliably reproduces against the latest development version of the go toolchain (and also against go-1.11.2)
  • It does not rely on the testing package anymore
package main

import (
	_ "net"
)

type A struct {
	buf [32]byte
}

type Z struct {
	buf [256]byte
}

var saved interface{}

func (a A) f(x interface{}) {
	xx := x.(Z)
	a.g(xx)
}

func (a A) g(z Z) {
	allocstuff()
	a.h(a, z)
}

func (a A) h(_ A, x interface{}) {
	saved = x
	return

	a.f(x)
}

func allocstuff() {
	m := make(map[int]int)
	for i := 0; i < 1000000; i++ {
		m[i] = i
	}
}

func main() {
	var z Z
	var a A
	a.f(z)
	allocstuff()
}

Running it, I get:

nickolai@kalahari:~/tmp/gobug2$ GOGC=1 ~/tmp/go/bin/go run bug.go
runtime: pointer 0xc0000ab8f8 to unused region of span span.base()=0xc000364000 span.limit=0xc000366000 span.state=1
runtime: found in object at *(0x54a3a0+0x248)
object=0x54a3a0 s=nil
fatal error: found bad pointer in Go heap (incorrect use of unsafe or cgo?)

runtime stack:
runtime.throw(0x4bad42, 0x3e)
	/home/nickolai/tmp/go/src/runtime/panic.go:608 +0x72 fp=0x7fc578ae7c70 sp=0x7fc578ae7c40 pc=0x428722
runtime.findObject(0xc0000ab8f8, 0x54a3a0, 0x248, 0x7fc57d637360, 0xc00002d770, 0xa)
	/home/nickolai/tmp/go/src/runtime/mbitmap.go:397 +0x3b4 fp=0x7fc578ae7cc0 sp=0x7fc578ae7c70 pc=0x411e34
runtime.scanblock(0x54a3a0, 0x1bb30, 0x7fc57d6409a6, 0xc00002d770, 0x0)
	/home/nickolai/tmp/go/src/runtime/mgcmark.go:1057 +0xa8 fp=0x7fc578ae7d20 sp=0x7fc578ae7cc0 pc=0x41cff8
runtime.markrootBlock(0x54a3a0, 0x1bb30, 0x7fc57d6409a6, 0xc00002d770, 0x0)
	/home/nickolai/tmp/go/src/runtime/mgcmark.go:251 +0x9c fp=0x7fc578ae7d58 sp=0x7fc578ae7d20 pc=0x41b41c
runtime.markroot(0xc00002d770, 0x3)
	/home/nickolai/tmp/go/src/runtime/mgcmark.go:166 +0x1b1 fp=0x7fc578ae7dd8 sp=0x7fc578ae7d58 pc=0x41b1c1
runtime.gcDrainN(0xc00002d770, 0x10000, 0x2f983c87bcb8a)
	/home/nickolai/tmp/go/src/runtime/mgcmark.go:1006 +0xff fp=0x7fc578ae7e08 sp=0x7fc578ae7dd8 pc=0x41ce1f
runtime.gcAssistAlloc1(0xc000000180, 0x10000)
	/home/nickolai/tmp/go/src/runtime/mgcmark.go:512 +0xf4 fp=0x7fc578ae7e58 sp=0x7fc578ae7e08 pc=0x41bb54
runtime.gcAssistAlloc.func1()
	/home/nickolai/tmp/go/src/runtime/mgcmark.go:423 +0x33 fp=0x7fc578ae7e78 sp=0x7fc578ae7e58 pc=0x44d073
runtime.systemstack(0x0)
	/home/nickolai/tmp/go/src/runtime/asm_amd64.s:351 +0x66 fp=0x7fc578ae7e80 sp=0x7fc578ae7e78 pc=0x44eef6
runtime.mstart()
	/home/nickolai/tmp/go/src/runtime/proc.go:1153 fp=0x7fc578ae7e88 sp=0x7fc578ae7e80 pc=0x42cc30

goroutine 1 [GC assist marking]:
runtime.systemstack_switch()
	/home/nickolai/tmp/go/src/runtime/asm_amd64.s:311 fp=0xc00005ba38 sp=0xc00005ba30 pc=0x44ee80
runtime.gcAssistAlloc(0xc000000180)
	/home/nickolai/tmp/go/src/runtime/mgcmark.go:422 +0x15c fp=0xc00005ba98 sp=0xc00005ba38 pc=0x41b8ec
runtime.mallocgc(0x400, 0x49c840, 0x101, 0xc000364000)
	/home/nickolai/tmp/go/src/runtime/malloc.go:843 +0x8d6 fp=0xc00005bb38 sp=0xc00005ba98 pc=0x40bb86
runtime.growslice(0x49c840, 0xc000364000, 0x40, 0x40, 0x41, 0xc000364000, 0x20, 0x40)
	/home/nickolai/tmp/go/src/runtime/slice.go:181 +0x1e4 fp=0xc00005bba0 sp=0xc00005bb38 pc=0x43ba84
runtime.(*hmap).newoverflow(0xc00005bcf8, 0x4990e0, 0xc0000c7e00, 0xc0000d4370)
	/home/nickolai/tmp/go/src/runtime/map.go:269 +0x183 fp=0xc00005bc00 sp=0xc00005bba0 pc=0x40c7c3
runtime.mapassign_fast64(0x4990e0, 0xc00005bcf8, 0x142d, 0xc0000cdfc8)
	/home/nickolai/tmp/go/src/runtime/map_fast64.go:162 +0x207 fp=0xc00005bc40 sp=0xc00005bc00 pc=0x40fab7
main.allocstuff()
	/home/nickolai/tmp/gobug2/bug.go:37 +0xad fp=0xc00005bd38 sp=0xc00005bc40 pc=0x481c8d
main.main()
	/home/nickolai/tmp/gobug2/bug.go:45 +0xad fp=0xc00005bf98 sp=0xc00005bd38 pc=0x481d6d
runtime.main()
	/home/nickolai/tmp/go/src/runtime/proc.go:200 +0x204 fp=0xc00005bfe0 sp=0xc00005bf98 pc=0x42a084
runtime.goexit()
	/home/nickolai/tmp/go/src/runtime/asm_amd64.s:1337 +0x1 fp=0xc00005bfe8 sp=0xc00005bfe0 pc=0x450f51

goroutine 2 [force gc (idle)]:
runtime.gopark(0x4bb330, 0x54ab10, 0x1410, 0x1)
	/home/nickolai/tmp/go/src/runtime/proc.go:301 +0xe6 fp=0xc00004afb0 sp=0xc00004af90 pc=0x42a456
runtime.goparkunlock(...)
	/home/nickolai/tmp/go/src/runtime/proc.go:307
runtime.forcegchelper()
	/home/nickolai/tmp/go/src/runtime/proc.go:250 +0xb6 fp=0xc00004afe0 sp=0xc00004afb0 pc=0x42a306
runtime.goexit()
	/home/nickolai/tmp/go/src/runtime/asm_amd64.s:1337 +0x1 fp=0xc00004afe8 sp=0xc00004afe0 pc=0x450f51
created by runtime.init.5
	/home/nickolai/tmp/go/src/runtime/proc.go:239 +0x35

goroutine 3 [GC sweep wait]:
runtime.gopark(0x4bb330, 0x54ac40, 0x140c, 0x1)
	/home/nickolai/tmp/go/src/runtime/proc.go:301 +0xe6 fp=0xc00004b7a8 sp=0xc00004b788 pc=0x42a456
runtime.goparkunlock(...)
	/home/nickolai/tmp/go/src/runtime/proc.go:307
runtime.bgsweep(0xc000022070)
	/home/nickolai/tmp/go/src/runtime/mgcsweep.go:89 +0x12d fp=0xc00004b7d8 sp=0xc00004b7a8 pc=0x41e97d
runtime.goexit()
	/home/nickolai/tmp/go/src/runtime/asm_amd64.s:1337 +0x1 fp=0xc00004b7e0 sp=0xc00004b7d8 pc=0x450f51
created by runtime.gcenable
	/home/nickolai/tmp/go/src/runtime/mgc.go:208 +0x58

goroutine 4 [finalizer wait]:
runtime.gopark(0x4bb330, 0x565fc8, 0x140f, 0x1)
	/home/nickolai/tmp/go/src/runtime/proc.go:301 +0xe6 fp=0xc00004bf58 sp=0xc00004bf38 pc=0x42a456
runtime.goparkunlock(...)
	/home/nickolai/tmp/go/src/runtime/proc.go:307
runtime.runfinq()
	/home/nickolai/tmp/go/src/runtime/mfinal.go:175 +0xa5 fp=0xc00004bfe0 sp=0xc00004bf58 pc=0x415b45
runtime.goexit()
	/home/nickolai/tmp/go/src/runtime/asm_amd64.s:1337 +0x1 fp=0xc00004bfe8 sp=0xc00004bfe0 pc=0x450f51
created by runtime.createfing
	/home/nickolai/tmp/go/src/runtime/mfinal.go:156 +0x61

goroutine 5 [GC worker (idle)]:
runtime.gopark(0x4bb1f8, 0xc000350000, 0x1417, 0x0)
	/home/nickolai/tmp/go/src/runtime/proc.go:301 +0xe6 fp=0xc00004a760 sp=0xc00004a740 pc=0x42a456
runtime.gcBgMarkWorker(0xc00002a000)
	/home/nickolai/tmp/go/src/runtime/mgc.go:1731 +0xfc fp=0xc00004a7d8 sp=0xc00004a760 pc=0x41932c
runtime.goexit()
	/home/nickolai/tmp/go/src/runtime/asm_amd64.s:1337 +0x1 fp=0xc00004a7e0 sp=0xc00004a7d8 pc=0x450f51
created by runtime.gcBgMarkStartWorkers
	/home/nickolai/tmp/go/src/runtime/mgc.go:1679 +0x77

goroutine 18 [GC worker (idle)]:
runtime.gopark(0x4bb1f8, 0xc000350010, 0x1417, 0x0)
	/home/nickolai/tmp/go/src/runtime/proc.go:301 +0xe6 fp=0xc000046760 sp=0xc000046740 pc=0x42a456
runtime.gcBgMarkWorker(0xc00002c500)
	/home/nickolai/tmp/go/src/runtime/mgc.go:1731 +0xfc fp=0xc0000467d8 sp=0xc000046760 pc=0x41932c
runtime.goexit()
	/home/nickolai/tmp/go/src/runtime/asm_amd64.s:1337 +0x1 fp=0xc0000467e0 sp=0xc0000467d8 pc=0x450f51
created by runtime.gcBgMarkStartWorkers
	/home/nickolai/tmp/go/src/runtime/mgc.go:1679 +0x77

goroutine 19 [GC worker (idle)]:
runtime.gopark(0x4bb1f8, 0xc000350020, 0x1417, 0x0)
	/home/nickolai/tmp/go/src/runtime/proc.go:301 +0xe6 fp=0xc000046f60 sp=0xc000046f40 pc=0x42a456
runtime.gcBgMarkWorker(0xc00002ea00)
	/home/nickolai/tmp/go/src/runtime/mgc.go:1731 +0xfc fp=0xc000046fd8 sp=0xc000046f60 pc=0x41932c
runtime.goexit()
	/home/nickolai/tmp/go/src/runtime/asm_amd64.s:1337 +0x1 fp=0xc000046fe0 sp=0xc000046fd8 pc=0x450f51
created by runtime.gcBgMarkStartWorkers
	/home/nickolai/tmp/go/src/runtime/mgc.go:1679 +0x77

goroutine 20 [GC worker (idle)]:
runtime.gopark(0x4bb1f8, 0xc000350030, 0x1417, 0x0)
	/home/nickolai/tmp/go/src/runtime/proc.go:301 +0xe6 fp=0xc000047760 sp=0xc000047740 pc=0x42a456
runtime.gcBgMarkWorker(0xc000030f00)
	/home/nickolai/tmp/go/src/runtime/mgc.go:1731 +0xfc fp=0xc0000477d8 sp=0xc000047760 pc=0x41932c
runtime.goexit()
	/home/nickolai/tmp/go/src/runtime/asm_amd64.s:1337 +0x1 fp=0xc0000477e0 sp=0xc0000477d8 pc=0x450f51
created by runtime.gcBgMarkStartWorkers
	/home/nickolai/tmp/go/src/runtime/mgc.go:1679 +0x77

goroutine 34 [GC worker (idle)]:
runtime.gopark(0x4bb1f8, 0xc000350040, 0x1417, 0x0)
	/home/nickolai/tmp/go/src/runtime/proc.go:301 +0xe6 fp=0xc00035a760 sp=0xc00035a740 pc=0x42a456
runtime.gcBgMarkWorker(0xc000033400)
	/home/nickolai/tmp/go/src/runtime/mgc.go:1731 +0xfc fp=0xc00035a7d8 sp=0xc00035a760 pc=0x41932c
runtime.goexit()
	/home/nickolai/tmp/go/src/runtime/asm_amd64.s:1337 +0x1 fp=0xc00035a7e0 sp=0xc00035a7d8 pc=0x450f51
created by runtime.gcBgMarkStartWorkers
	/home/nickolai/tmp/go/src/runtime/mgc.go:1679 +0x77

goroutine 6 [GC worker (idle)]:
runtime.gopark(0x4bb1f8, 0xc000016300, 0x1417, 0x0)
	/home/nickolai/tmp/go/src/runtime/proc.go:301 +0xe6 fp=0xc00004c760 sp=0xc00004c740 pc=0x42a456
runtime.gcBgMarkWorker(0xc000035900)
	/home/nickolai/tmp/go/src/runtime/mgc.go:1731 +0xfc fp=0xc00004c7d8 sp=0xc00004c760 pc=0x41932c
runtime.goexit()
	/home/nickolai/tmp/go/src/runtime/asm_amd64.s:1337 +0x1 fp=0xc00004c7e0 sp=0xc00004c7d8 pc=0x450f51
created by runtime.gcBgMarkStartWorkers
	/home/nickolai/tmp/go/src/runtime/mgc.go:1679 +0x77

goroutine 21 [GC worker (idle)]:
runtime.gopark(0x4bb1f8, 0xc000016310, 0x1417, 0x0)
	/home/nickolai/tmp/go/src/runtime/proc.go:301 +0xe6 fp=0xc000047f60 sp=0xc000047f40 pc=0x42a456
runtime.gcBgMarkWorker(0xc000038000)
	/home/nickolai/tmp/go/src/runtime/mgc.go:1731 +0xfc fp=0xc000047fd8 sp=0xc000047f60 pc=0x41932c
runtime.goexit()
	/home/nickolai/tmp/go/src/runtime/asm_amd64.s:1337 +0x1 fp=0xc000047fe0 sp=0xc000047fd8 pc=0x450f51
created by runtime.gcBgMarkStartWorkers
	/home/nickolai/tmp/go/src/runtime/mgc.go:1679 +0x77

goroutine 7 [GC worker (idle)]:
runtime.gopark(0x4bb1f8, 0xc00035e000, 0x1417, 0x0)
	/home/nickolai/tmp/go/src/runtime/proc.go:301 +0xe6 fp=0xc00004cf60 sp=0xc00004cf40 pc=0x42a456
runtime.gcBgMarkWorker(0xc00003a500)
	/home/nickolai/tmp/go/src/runtime/mgc.go:1731 +0xfc fp=0xc00004cfd8 sp=0xc00004cf60 pc=0x41932c
runtime.goexit()
	/home/nickolai/tmp/go/src/runtime/asm_amd64.s:1337 +0x1 fp=0xc00004cfe0 sp=0xc00004cfd8 pc=0x450f51
created by runtime.gcBgMarkStartWorkers
	/home/nickolai/tmp/go/src/runtime/mgc.go:1679 +0x77
exit status 2
nickolai@kalahari:~/tmp/gobug2$ 

@zeldovich
Copy link
Author

And a version that triggers the bug even without GOGC=1:

package main

import (
	_ "net"
)

type Z struct {
	buf [256]byte
}

var saved interface{}

func f(x interface{}) {
	z := x.(Z)
	g(z)
}

func g(z Z) {
	allocstuff()
	h(z, z, z)
}

func h(_ Z, _ Z, x interface{}) {
	saved = x
	return

	f(x)
}

func allocstuff() {
	m := make(map[int]int)
	for i := 0; i < 1000000; i++ {
		m[i] = i
	}
}

func main() {
	var z Z
	f(z)
	allocstuff()
}

leading to:

nickolai@kalahari:~/tmp/gobug2$ ~/tmp/go/bin/go version
go version devel +2b58ca6e3d Thu Nov 29 14:00:26 2018 +0000 linux/amd64
nickolai@kalahari:~/tmp/gobug2$ ~/tmp/go/bin/go run bug.go 
runtime: pointer 0xc00020fa58 to unused region of span span.base()=0xc0003fa000 span.limit=0xc0003fbf80 span.state=1
runtime: found in object at *(0x54a3a0+0x248)
object=0x54a3a0 s=nil
fatal error: found bad pointer in Go heap (incorrect use of unsafe or cgo?)

runtime stack:
runtime.throw(0x4bad42, 0x3e)
	/home/nickolai/tmp/go/src/runtime/panic.go:608 +0x72 fp=0x7f26135fec78 sp=0x7f26135fec48 pc=0x428722
runtime.findObject(0xc00020fa58, 0x54a3a0, 0x248, 0x7f26167eb360, 0xc00002d770, 0xa)
	/home/nickolai/tmp/go/src/runtime/mbitmap.go:397 +0x3b4 fp=0x7f26135fecc8 sp=0x7f26135fec78 pc=0x411e34
runtime.scanblock(0x54a3a0, 0x1bb30, 0x7f26167f49a6, 0xc00002d770, 0x0)
	/home/nickolai/tmp/go/src/runtime/mgcmark.go:1057 +0xa8 fp=0x7f26135fed28 sp=0x7f26135fecc8 pc=0x41cff8
runtime.markrootBlock(0x54a3a0, 0x1bb30, 0x7f26167f49a6, 0xc00002d770, 0x0)
	/home/nickolai/tmp/go/src/runtime/mgcmark.go:251 +0x9c fp=0x7f26135fed60 sp=0x7f26135fed28 pc=0x41b41c
runtime.markroot(0xc00002d770, 0x7f2600000003)
	/home/nickolai/tmp/go/src/runtime/mgcmark.go:166 +0x1b1 fp=0x7f26135fede0 sp=0x7f26135fed60 pc=0x41b1c1
runtime.gcDrain(0xc00002d770, 0x7)
	/home/nickolai/tmp/go/src/runtime/mgcmark.go:886 +0x10e fp=0x7f26135fee38 sp=0x7f26135fede0 pc=0x41c9ee
runtime.gcBgMarkWorker.func2()
	/home/nickolai/tmp/go/src/runtime/mgc.go:1821 +0x166 fp=0x7f26135fee78 sp=0x7f26135fee38 pc=0x44cf06
runtime.systemstack(0x0)
	/home/nickolai/tmp/go/src/runtime/asm_amd64.s:351 +0x66 fp=0x7f26135fee80 sp=0x7f26135fee78 pc=0x44eef6
runtime.mstart()
	/home/nickolai/tmp/go/src/runtime/proc.go:1153 fp=0x7f26135fee88 sp=0x7f26135fee80 pc=0x42cc30

goroutine 18 [GC worker (idle)]:
runtime.systemstack_switch()
	/home/nickolai/tmp/go/src/runtime/asm_amd64.s:311 fp=0xc000046760 sp=0xc000046758 pc=0x44ee80
runtime.gcBgMarkWorker(0xc00002c500)
	/home/nickolai/tmp/go/src/runtime/mgc.go:1785 +0x1b8 fp=0xc0000467d8 sp=0xc000046760 pc=0x4193e8
runtime.goexit()
	/home/nickolai/tmp/go/src/runtime/asm_amd64.s:1337 +0x1 fp=0xc0000467e0 sp=0xc0000467d8 pc=0x450f51
created by runtime.gcBgMarkStartWorkers
	/home/nickolai/tmp/go/src/runtime/mgc.go:1679 +0x77

goroutine 1 [runnable]:
runtime.growslice(0x49c840, 0x0, 0x0, 0x0, 0x1, 0xc00005bd30, 0x410033, 0x4990e0)
	/home/nickolai/tmp/go/src/runtime/slice.go:76 +0x62e fp=0xc00005bce0 sp=0xc00005bcd8 pc=0x43bece
runtime.(*hmap).newoverflow(0xc00005be38, 0x4990e0, 0xc006145fd0, 0xc0004e0240)
	/home/nickolai/tmp/go/src/runtime/map.go:269 +0x183 fp=0xc00005bd40 sp=0xc00005bce0 pc=0x40c7c3
runtime.mapassign_fast64(0x4990e0, 0xc00005be38, 0x6801f, 0xc0058badf8)
	/home/nickolai/tmp/go/src/runtime/map_fast64.go:162 +0x207 fp=0xc00005bd80 sp=0xc00005bd40 pc=0x40fab7
main.allocstuff()
	/home/nickolai/tmp/gobug2/bug.go:33 +0xad fp=0xc00005be78 sp=0xc00005bd80 pc=0x481c9d
main.main()
	/home/nickolai/tmp/gobug2/bug.go:40 +0x68 fp=0xc00005bf98 sp=0xc00005be78 pc=0x481d38
runtime.main()
	/home/nickolai/tmp/go/src/runtime/proc.go:200 +0x204 fp=0xc00005bfe0 sp=0xc00005bf98 pc=0x42a084
runtime.goexit()
	/home/nickolai/tmp/go/src/runtime/asm_amd64.s:1337 +0x1 fp=0xc00005bfe8 sp=0xc00005bfe0 pc=0x450f51

goroutine 2 [force gc (idle)]:
runtime.gopark(0x4bb330, 0x54ab10, 0x1410, 0x1)
	/home/nickolai/tmp/go/src/runtime/proc.go:301 +0xe6 fp=0xc00004afb0 sp=0xc00004af90 pc=0x42a456
runtime.goparkunlock(...)
	/home/nickolai/tmp/go/src/runtime/proc.go:307
runtime.forcegchelper()
	/home/nickolai/tmp/go/src/runtime/proc.go:250 +0xb6 fp=0xc00004afe0 sp=0xc00004afb0 pc=0x42a306
runtime.goexit()
	/home/nickolai/tmp/go/src/runtime/asm_amd64.s:1337 +0x1 fp=0xc00004afe8 sp=0xc00004afe0 pc=0x450f51
created by runtime.init.5
	/home/nickolai/tmp/go/src/runtime/proc.go:239 +0x35

goroutine 3 [GC sweep wait]:
runtime.gopark(0x4bb330, 0x54ac40, 0x140c, 0x1)
	/home/nickolai/tmp/go/src/runtime/proc.go:301 +0xe6 fp=0xc00004b7a8 sp=0xc00004b788 pc=0x42a456
runtime.goparkunlock(...)
	/home/nickolai/tmp/go/src/runtime/proc.go:307
runtime.bgsweep(0xc000022070)
	/home/nickolai/tmp/go/src/runtime/mgcsweep.go:89 +0x12d fp=0xc00004b7d8 sp=0xc00004b7a8 pc=0x41e97d
runtime.goexit()
	/home/nickolai/tmp/go/src/runtime/asm_amd64.s:1337 +0x1 fp=0xc00004b7e0 sp=0xc00004b7d8 pc=0x450f51
created by runtime.gcenable
	/home/nickolai/tmp/go/src/runtime/mgc.go:208 +0x58

goroutine 4 [finalizer wait]:
runtime.gopark(0x4bb330, 0x565fc8, 0x140f, 0x1)
	/home/nickolai/tmp/go/src/runtime/proc.go:301 +0xe6 fp=0xc00004bf58 sp=0xc00004bf38 pc=0x42a456
runtime.goparkunlock(...)
	/home/nickolai/tmp/go/src/runtime/proc.go:307
runtime.runfinq()
	/home/nickolai/tmp/go/src/runtime/mfinal.go:175 +0xa5 fp=0xc00004bfe0 sp=0xc00004bf58 pc=0x415b45
runtime.goexit()
	/home/nickolai/tmp/go/src/runtime/asm_amd64.s:1337 +0x1 fp=0xc00004bfe8 sp=0xc00004bfe0 pc=0x450f51
created by runtime.createfing
	/home/nickolai/tmp/go/src/runtime/mfinal.go:156 +0x61

goroutine 5 [GC worker (idle)]:
runtime.gopark(0x4bb1f8, 0xc000612000, 0x1417, 0x0)
	/home/nickolai/tmp/go/src/runtime/proc.go:301 +0xe6 fp=0xc00004a760 sp=0xc00004a740 pc=0x42a456
runtime.gcBgMarkWorker(0xc00002a000)
	/home/nickolai/tmp/go/src/runtime/mgc.go:1731 +0xfc fp=0xc00004a7d8 sp=0xc00004a760 pc=0x41932c
runtime.goexit()
	/home/nickolai/tmp/go/src/runtime/asm_amd64.s:1337 +0x1 fp=0xc00004a7e0 sp=0xc00004a7d8 pc=0x450f51
created by runtime.gcBgMarkStartWorkers
	/home/nickolai/tmp/go/src/runtime/mgc.go:1679 +0x77

goroutine 34 [GC worker (idle)]:
runtime.gopark(0x4bb1f8, 0xc00061e000, 0x1417, 0x0)
	/home/nickolai/tmp/go/src/runtime/proc.go:301 +0xe6 fp=0xc00061a760 sp=0xc00061a740 pc=0x42a456
runtime.gcBgMarkWorker(0xc00002ea00)
	/home/nickolai/tmp/go/src/runtime/mgc.go:1731 +0xfc fp=0xc00061a7d8 sp=0xc00061a760 pc=0x41932c
runtime.goexit()
	/home/nickolai/tmp/go/src/runtime/asm_amd64.s:1337 +0x1 fp=0xc00061a7e0 sp=0xc00061a7d8 pc=0x450f51
created by runtime.gcBgMarkStartWorkers
	/home/nickolai/tmp/go/src/runtime/mgc.go:1679 +0x77

goroutine 19 [GC worker (idle)]:
runtime.gopark(0x4bb1f8, 0xc000612010, 0x1417, 0x0)
	/home/nickolai/tmp/go/src/runtime/proc.go:301 +0xe6 fp=0xc000046f60 sp=0xc000046f40 pc=0x42a456
runtime.gcBgMarkWorker(0xc000030f00)
	/home/nickolai/tmp/go/src/runtime/mgc.go:1731 +0xfc fp=0xc000046fd8 sp=0xc000046f60 pc=0x41932c
runtime.goexit()
	/home/nickolai/tmp/go/src/runtime/asm_amd64.s:1337 +0x1 fp=0xc000046fe0 sp=0xc000046fd8 pc=0x450f51
created by runtime.gcBgMarkStartWorkers
	/home/nickolai/tmp/go/src/runtime/mgc.go:1679 +0x77

goroutine 35 [GC worker (idle)]:
runtime.gopark(0x4bb1f8, 0xc000612020, 0x1417, 0x0)
	/home/nickolai/tmp/go/src/runtime/proc.go:301 +0xe6 fp=0xc00061af60 sp=0xc00061af40 pc=0x42a456
runtime.gcBgMarkWorker(0xc000033400)
	/home/nickolai/tmp/go/src/runtime/mgc.go:1731 +0xfc fp=0xc00061afd8 sp=0xc00061af60 pc=0x41932c
runtime.goexit()
	/home/nickolai/tmp/go/src/runtime/asm_amd64.s:1337 +0x1 fp=0xc00061afe0 sp=0xc00061afd8 pc=0x450f51
created by runtime.gcBgMarkStartWorkers
	/home/nickolai/tmp/go/src/runtime/mgc.go:1679 +0x77

goroutine 36 [GC worker (idle)]:
runtime.gopark(0x4bb1f8, 0xc000612030, 0x1417, 0x0)
	/home/nickolai/tmp/go/src/runtime/proc.go:301 +0xe6 fp=0xc00061b760 sp=0xc00061b740 pc=0x42a456
runtime.gcBgMarkWorker(0xc000035900)
	/home/nickolai/tmp/go/src/runtime/mgc.go:1731 +0xfc fp=0xc00061b7d8 sp=0xc00061b760 pc=0x41932c
runtime.goexit()
	/home/nickolai/tmp/go/src/runtime/asm_amd64.s:1337 +0x1 fp=0xc00061b7e0 sp=0xc00061b7d8 pc=0x450f51
created by runtime.gcBgMarkStartWorkers
	/home/nickolai/tmp/go/src/runtime/mgc.go:1679 +0x77

goroutine 37 [GC worker (idle)]:
runtime.gopark(0x4bb1f8, 0xc00001c310, 0x1417, 0x0)
	/home/nickolai/tmp/go/src/runtime/proc.go:301 +0xe6 fp=0xc00061bf60 sp=0xc00061bf40 pc=0x42a456
runtime.gcBgMarkWorker(0xc000038000)
	/home/nickolai/tmp/go/src/runtime/mgc.go:1731 +0xfc fp=0xc00061bfd8 sp=0xc00061bf60 pc=0x41932c
runtime.goexit()
	/home/nickolai/tmp/go/src/runtime/asm_amd64.s:1337 +0x1 fp=0xc00061bfe0 sp=0xc00061bfd8 pc=0x450f51
created by runtime.gcBgMarkStartWorkers
	/home/nickolai/tmp/go/src/runtime/mgc.go:1679 +0x77

goroutine 6 [GC worker (idle)]:
runtime.gopark(0x4bb1f8, 0xc000612040, 0x1417, 0x0)
	/home/nickolai/tmp/go/src/runtime/proc.go:301 +0xe6 fp=0xc00004c760 sp=0xc00004c740 pc=0x42a456
runtime.gcBgMarkWorker(0xc00003a500)
	/home/nickolai/tmp/go/src/runtime/mgc.go:1731 +0xfc fp=0xc00004c7d8 sp=0xc00004c760 pc=0x41932c
runtime.goexit()
	/home/nickolai/tmp/go/src/runtime/asm_amd64.s:1337 +0x1 fp=0xc00004c7e0 sp=0xc00004c7d8 pc=0x450f51
created by runtime.gcBgMarkStartWorkers
	/home/nickolai/tmp/go/src/runtime/mgc.go:1679 +0x77
exit status 2
nickolai@kalahari:~/tmp/gobug2$ 

It takes a few tries without GOGC=1, but with GOGC=1 it's consistently reproducible for me.

@dgryski
Copy link
Contributor

dgryski commented Nov 29, 2018

Does this trigger in 1.10 ? Is it worth trying to bisect ?

@zeldovich
Copy link
Author

The same bug shows up with go-1.10 and go-1.10.3. I didn't bother going back further.

@ianlancetaylor
Copy link
Contributor

CC @aclements

@ianlancetaylor ianlancetaylor added NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. release-blocker labels Nov 29, 2018
@ianlancetaylor ianlancetaylor added this to the Go1.12 milestone Nov 29, 2018
@rotemh
Copy link

rotemh commented Dec 2, 2018

On go 1.11, this version (no imports and no special flags) also produces the bug.

package main

type Z struct {
	buf [256]byte
}

var saved interface{}

func f(x interface{}) {
	z := x.(Z)
	g(z)
}

func g(z Z) {
	allocstuff()
	h(z, z, z)
}

func h(_ Z, _ Z, x interface{}) {
	saved = x
	return

	f(x)
}

func allocstuff() {
	m := make(map[int]int)
	for i := 0; i < 1000000; i++ {
		m[i] = i
	}
}

func main() {
	var z Z
	f(z)
	allocstuff()
}

Result --

runtime: pointer 0xc0001d5958 to unallocated span span.base()=0xc0001d0000 span.limit=0xc0001d8000 span.state=0
runtime: found in object at *(0x10ba700+0xc8)
object=0x10ba700 s=nil
fatal error: found bad pointer in Go heap (incorrect use of unsafe or cgo?)

runtime stack:
runtime.throw(0x106fbce, 0x3e)
	/usr/local/Cellar/go/1.11/libexec/src/runtime/panic.go:608 +0x72 fp=0x700003802cc8 sp=0x700003802c98 pc=0x1022562
runtime.findObject(0xc0001d5958, 0x10ba700, 0xc8, 0x1208130, 0xc000025770, 0x0)
	/usr/local/Cellar/go/1.11/libexec/src/runtime/mbitmap.go:399 +0x3b6 fp=0x700003802d18 sp=0x700003802cc8 pc=0x100e036
runtime.scanblock(0x10ba700, 0x1c370, 0x1211868, 0xc000025770)
	/usr/local/Cellar/go/1.11/libexec/src/runtime/mgcmark.go:1048 +0xa9 fp=0x700003802d70 sp=0x700003802d18 pc=0x1017be9
runtime.markrootBlock(0x10ba700, 0x1c370, 0x1211868, 0xc000025770, 0x0)
	/usr/local/Cellar/go/1.11/libexec/src/runtime/mgcmark.go:294 +0x90 fp=0x700003802da0 sp=0x700003802d70 pc=0x10161d0
runtime.markroot(0xc000025770, 0x3)
	/usr/local/Cellar/go/1.11/libexec/src/runtime/mgcmark.go:200 +0x1a9 fp=0x700003802e20 sp=0x700003802da0 pc=0x1015f79
runtime.gcDrainN(0xc000025770, 0x10000, 0x200)
	/usr/local/Cellar/go/1.11/libexec/src/runtime/mgcmark.go:998 +0x107 fp=0x700003802e50 sp=0x700003802e20 pc=0x1017a37
runtime.gcAssistAlloc1(0xc000000300, 0x10000)
	/usr/local/Cellar/go/1.11/libexec/src/runtime/mgcmark.go:557 +0xf9 fp=0x700003802ea8 sp=0x700003802e50 pc=0x10168d9
runtime.gcAssistAlloc.func1()
	/usr/local/Cellar/go/1.11/libexec/src/runtime/mgcmark.go:468 +0x33 fp=0x700003802ec8 sp=0x700003802ea8 pc=0x10455d3
runtime.systemstack(0x0)
	/usr/local/Cellar/go/1.11/libexec/src/runtime/asm_amd64.s:351 +0x66 fp=0x700003802ed0 sp=0x700003802ec8 pc=0x1047146
runtime.mstart()
	/usr/local/Cellar/go/1.11/libexec/src/runtime/proc.go:1229 fp=0x700003802ed8 sp=0x700003802ed0 pc=0x1026cd0

goroutine 1 [GC assist marking]:
runtime.systemstack_switch()
	/usr/local/Cellar/go/1.11/libexec/src/runtime/asm_amd64.s:311 fp=0xc000558b00 sp=0xc000558af8 pc=0x10470d0
runtime.gcAssistAlloc(0xc000000300)
	/usr/local/Cellar/go/1.11/libexec/src/runtime/mgcmark.go:467 +0x162 fp=0xc000558b40 sp=0xc000558b00 pc=0x10166d2
runtime.mallocgc(0x18, 0x1057580, 0x1, 0xc00097a700)
	/usr/local/Cellar/go/1.11/libexec/src/runtime/malloc.go:807 +0x909 fp=0xc000558be0 sp=0xc000558b40 pc=0x1009f09
runtime.newobject(0x1057580, 0x0)
	/usr/local/Cellar/go/1.11/libexec/src/runtime/malloc.go:1032 +0x38 fp=0xc000558c10 sp=0xc000558be0 pc=0x100a178
runtime.(*hmap).createOverflow(...)
	/usr/local/Cellar/go/1.11/libexec/src/runtime/map.go:273
runtime.(*hmap).newoverflow(0xc000558e38, 0x105bdc0, 0xc00097e990, 0x2)
	/usr/local/Cellar/go/1.11/libexec/src/runtime/map.go:261 +0x1c8 fp=0xc000558c70 sp=0xc000558c10 pc=0x100ab78
runtime.evacuate_fast64(0x105bdc0, 0xc000558e38, 0x11)
	/usr/local/Cellar/go/1.11/libexec/src/runtime/map_fast64.go:374 +0x2af fp=0xc000558d18 sp=0xc000558c70 pc=0x100d47f
runtime.growWork_fast64(0x105bdc0, 0xc000558e38, 0x4a69)
	/usr/local/Cellar/go/1.11/libexec/src/runtime/map_fast64.go:321 +0x93 fp=0xc000558d40 sp=0xc000558d18 pc=0x100d1b3
runtime.mapassign_fast64(0x105bdc0, 0xc000558e38, 0x1a011, 0xc000d2c120)
	/usr/local/Cellar/go/1.11/libexec/src/runtime/map_fast64.go:115 +0x272 fp=0xc000558d80 sp=0xc000558d40 pc=0x100d062
main.allocstuff()
	/private/var/folders/jx/6p7nwycs1jggxn5m9vlfvqy40000gn/T/CodeRunner/Go/Untitled 4.go:29 +0xad fp=0xc000558e78 sp=0xc000558d80 pc=0x104ebbd
main.main()
	/private/var/folders/jx/6p7nwycs1jggxn5m9vlfvqy40000gn/T/CodeRunner/Go/Untitled 4.go:36 +0x68 fp=0xc000558f98 sp=0xc000558e78 pc=0x104ec58
runtime.main()
	/usr/local/Cellar/go/1.11/libexec/src/runtime/proc.go:201 +0x207 fp=0xc000558fe0 sp=0xc000558f98 pc=0x1023ed7
runtime.goexit()
	/usr/local/Cellar/go/1.11/libexec/src/runtime/asm_amd64.s:1333 +0x1 fp=0xc000558fe8 sp=0xc000558fe0 pc=0x1049001

goroutine 2 [force gc (idle)]:
runtime.gopark(0x106ff88, 0x10ba880, 0x1410, 0x1)
	/usr/local/Cellar/go/1.11/libexec/src/runtime/proc.go:302 +0xeb fp=0xc000034f80 sp=0xc000034f60 pc=0x10242bb
runtime.goparkunlock(0x10ba880, 0x1410, 0x1)
	/usr/local/Cellar/go/1.11/libexec/src/runtime/proc.go:308 +0x53 fp=0xc000034fb0 sp=0xc000034f80 pc=0x1024363
runtime.forcegchelper()
	/usr/local/Cellar/go/1.11/libexec/src/runtime/proc.go:251 +0xb3 fp=0xc000034fe0 sp=0xc000034fb0 pc=0x1024133
runtime.goexit()
	/usr/local/Cellar/go/1.11/libexec/src/runtime/asm_amd64.s:1333 +0x1 fp=0xc000034fe8 sp=0xc000034fe0 pc=0x1049001
created by runtime.init.4
	/usr/local/Cellar/go/1.11/libexec/src/runtime/proc.go:240 +0x35

goroutine 3 [GC sweep wait]:
runtime.gopark(0x106ff88, 0x10ba920, 0x104140c, 0x1)
	/usr/local/Cellar/go/1.11/libexec/src/runtime/proc.go:302 +0xeb fp=0xc000035780 sp=0xc000035760 pc=0x10242bb
runtime.goparkunlock(0x10ba920, 0x107140c, 0x1)
	/usr/local/Cellar/go/1.11/libexec/src/runtime/proc.go:308 +0x53 fp=0xc0000357b0 sp=0xc000035780 pc=0x1024363
runtime.bgsweep(0xc00001a070)
	/usr/local/Cellar/go/1.11/libexec/src/runtime/mgcsweep.go:71 +0x102 fp=0xc0000357d8 sp=0xc0000357b0 pc=0x1019062
runtime.goexit()
	/usr/local/Cellar/go/1.11/libexec/src/runtime/asm_amd64.s:1333 +0x1 fp=0xc0000357e0 sp=0xc0000357d8 pc=0x1049001
created by runtime.gcenable
	/usr/local/Cellar/go/1.11/libexec/src/runtime/mgc.go:216 +0x58

goroutine 4 [GC worker (idle)]:
runtime.gopark(0x106fe30, 0xc0000120d0, 0x1417, 0x0)
	/usr/local/Cellar/go/1.11/libexec/src/runtime/proc.go:302 +0xeb fp=0xc000034760 sp=0xc000034740 pc=0x10242bb
runtime.gcBgMarkWorker(0xc000022000)
	/usr/local/Cellar/go/1.11/libexec/src/runtime/mgc.go:1772 +0xfc fp=0xc0000347d8 sp=0xc000034760 pc=0x10142fc
runtime.goexit()
	/usr/local/Cellar/go/1.11/libexec/src/runtime/asm_amd64.s:1333 +0x1 fp=0xc0000347e0 sp=0xc0000347d8 pc=0x1049001
created by runtime.gcBgMarkStartWorkers
	/usr/local/Cellar/go/1.11/libexec/src/runtime/mgc.go:1720 +0x77

goroutine 5 [GC worker (idle)]:
runtime.gopark(0x106fe30, 0xc0005da000, 0x1417, 0x0)
	/usr/local/Cellar/go/1.11/libexec/src/runtime/proc.go:302 +0xeb fp=0xc000035f60 sp=0xc000035f40 pc=0x10242bb
runtime.gcBgMarkWorker(0xc000024500)
	/usr/local/Cellar/go/1.11/libexec/src/runtime/mgc.go:1772 +0xfc fp=0xc000035fd8 sp=0xc000035f60 pc=0x10142fc
runtime.goexit()
	/usr/local/Cellar/go/1.11/libexec/src/runtime/asm_amd64.s:1333 +0x1 fp=0xc000035fe0 sp=0xc000035fd8 pc=0x1049001
created by runtime.gcBgMarkStartWorkers
	/usr/local/Cellar/go/1.11/libexec/src/runtime/mgc.go:1720 +0x77

goroutine 17 [GC worker (idle)]:
runtime.gopark(0x106fe30, 0xc0005de000, 0x1417, 0x0)
	/usr/local/Cellar/go/1.11/libexec/src/runtime/proc.go:302 +0xeb fp=0xc000030760 sp=0xc000030740 pc=0x10242bb
runtime.gcBgMarkWorker(0xc000026a00)
	/usr/local/Cellar/go/1.11/libexec/src/runtime/mgc.go:1772 +0xfc fp=0xc0000307d8 sp=0xc000030760 pc=0x10142fc
runtime.goexit()
	/usr/local/Cellar/go/1.11/libexec/src/runtime/asm_amd64.s:1333 +0x1 fp=0xc0000307e0 sp=0xc0000307d8 pc=0x1049001
created by runtime.gcBgMarkStartWorkers
	/usr/local/Cellar/go/1.11/libexec/src/runtime/mgc.go:1720 +0x77

goroutine 33 [GC worker (idle)]:
runtime.gopark(0x106fe30, 0xc0000120e0, 0x1417, 0x0)
	/usr/local/Cellar/go/1.11/libexec/src/runtime/proc.go:302 +0xeb fp=0xc0005e4760 sp=0xc0005e4740 pc=0x10242bb
runtime.gcBgMarkWorker(0xc000028f00)
	/usr/local/Cellar/go/1.11/libexec/src/runtime/mgc.go:1772 +0xfc fp=0xc0005e47d8 sp=0xc0005e4760 pc=0x10142fc
runtime.goexit()
	/usr/local/Cellar/go/1.11/libexec/src/runtime/asm_amd64.s:1333 +0x1 fp=0xc0005e47e0 sp=0xc0005e47d8 pc=0x1049001
created by runtime.gcBgMarkStartWorkers
	/usr/local/Cellar/go/1.11/libexec/src/runtime/mgc.go:1720 +0x77

@mark-rushakoff
Copy link
Contributor

I've poked at this a bit more, using go version devel +950100a95c Fri Nov 30 19:11:39 2018 +0000 darwin/amd64 and @rotemh's reproducer above this comment. A few things I've noticed:

Running with GOGC=1 simplifies the stack trace a bit by removing the number of GC workers.

On my machine, the object is always at the same address. The first line of the output varies between pointer <addr> to unallocated span and pointer <addr> to unused region of span, as shown in previous comments in this thread.

The crash seems to always while growing the map in the allocstuff function, and the trace there seems to vary with whether it's an unallocated span or unused region of span:

$ GOMAXPROCS=1 gotip run a.go
runtime: pointer 0xc000325b78 to unused region of span span.base()=0xc000056000 span.limit=0xc000057f80 span.state=1
runtime: found in object at *(0x10bd640+0xf8)
object=0x10bd640 s=nil
fatal error: found bad pointer in Go heap (incorrect use of unsafe or cgo?)

runtime stack:
runtime.throw(0x10709c7, 0x3e)
	/Users/mr/gotip/src/github.com/golang/go/src/runtime/panic.go:608 +0x72 fp=0x7ffeefbff3e8 sp=0x7ffeefbff3b8 pc=0x1022fe2
runtime.findObject(0xc000325b78, 0x10bd640, 0xf8, 0x0, 0x0, 0x0)
	/Users/mr/gotip/src/github.com/golang/go/src/runtime/mbitmap.go:397 +0x3b4 fp=0x7ffeefbff438 sp=0x7ffeefbff3e8 pc=0x100e1e4
runtime.scanblock(0x10bd640, 0x1b410, 0x1212869, 0xc000021270, 0x0)
	/Users/mr/gotip/src/github.com/golang/go/src/runtime/mgcmark.go:1057 +0xa8 fp=0x7ffeefbff498 sp=0x7ffeefbff438 pc=0x1018618
runtime.markrootBlock(0x10bd640, 0x1b410, 0x1212869, 0xc000021270, 0x0)
	/Users/mr/gotip/src/github.com/golang/go/src/runtime/mgcmark.go:251 +0x9c fp=0x7ffeefbff4d0 sp=0x7ffeefbff498 pc=0x1016a3c
runtime.markroot(0xc000021270, 0xdf23400000003)
	/Users/mr/gotip/src/github.com/golang/go/src/runtime/mgcmark.go:166 +0x1b1 fp=0x7ffeefbff550 sp=0x7ffeefbff4d0 pc=0x10167e1
runtime.gcDrain(0xc000021270, 0xb)
	/Users/mr/gotip/src/github.com/golang/go/src/runtime/mgcmark.go:886 +0x10e fp=0x7ffeefbff5a8 sp=0x7ffeefbff550 pc=0x101800e
runtime.gcBgMarkWorker.func2()
	/Users/mr/gotip/src/github.com/golang/go/src/runtime/mgc.go:1881 +0x180 fp=0x7ffeefbff5e8 sp=0x7ffeefbff5a8 pc=0x1044940
runtime.systemstack(0x0)
	/Users/mr/gotip/src/github.com/golang/go/src/runtime/asm_amd64.s:351 +0x66 fp=0x7ffeefbff5f0 sp=0x7ffeefbff5e8 pc=0x1046686
runtime.mstart()
	/Users/mr/gotip/src/github.com/golang/go/src/runtime/proc.go:1153 fp=0x7ffeefbff5f8 sp=0x7ffeefbff5f0 pc=0x1027390

goroutine 1 [runnable]:
runtime.evacuate_fast64(0x105bec0, 0xc00007cc48, 0x18d0)
	/Users/mr/gotip/src/github.com/golang/go/src/runtime/map_fast64.go:364 +0x477 fp=0xc00007cb28 sp=0xc00007cb20 pc=0x100d827
runtime.growWork_fast64(0x105bec0, 0xc00007cc48, 0x17854)
	/Users/mr/gotip/src/github.com/golang/go/src/runtime/map_fast64.go:360 +0x93 fp=0xc00007cb50 sp=0xc00007cb28 pc=0x100d393
runtime.mapassign_fast64(0x105bec0, 0xc00007cc48, 0x697ae, 0xc002e10f68)
	/Users/mr/gotip/src/github.com/golang/go/src/runtime/map_fast64.go:115 +0x29c fp=0xc00007cb90 sp=0xc00007cb50 pc=0x100d22c
main.allocstuff()
	/tmp/e/f/a.go:31 +0xad fp=0xc00007cc88 sp=0xc00007cb90 pc=0x104e30d
main.main()
	/tmp/e/f/a.go:38 +0x9b fp=0xc00007cf98 sp=0xc00007cc88 pc=0x104e3db
runtime.main()
	/Users/mr/gotip/src/github.com/golang/go/src/runtime/proc.go:200 +0x204 fp=0xc00007cfe0 sp=0xc00007cf98 pc=0x1024934
runtime.goexit()
	/Users/mr/gotip/src/github.com/golang/go/src/runtime/asm_amd64.s:1337 +0x1 fp=0xc00007cfe8 sp=0xc00007cfe0 pc=0x1048541
$ GOMAXPROCS=1 gotip run a.go
runtime: pointer 0xc000325b78 to unallocated span span.base()=0xc0001d0000 span.limit=0xc000328000 span.state=3
runtime: found in object at *(0x10bd640+0xf8)
object=0x10bd640 s=nil
fatal error: found bad pointer in Go heap (incorrect use of unsafe or cgo?)

runtime stack:
runtime.throw(0x10709c7, 0x3e)
	/Users/mr/gotip/src/github.com/golang/go/src/runtime/panic.go:608 +0x72 fp=0x7ffeefbff3e0 sp=0x7ffeefbff3b0 pc=0x1022fe2
runtime.findObject(0xc000325b78, 0x10bd640, 0xf8, 0x0, 0x0, 0x0)
	/Users/mr/gotip/src/github.com/golang/go/src/runtime/mbitmap.go:397 +0x3b4 fp=0x7ffeefbff430 sp=0x7ffeefbff3e0 pc=0x100e1e4
runtime.scanblock(0x10bd640, 0x1b410, 0x1212869, 0xc000021270, 0x0)
	/Users/mr/gotip/src/github.com/golang/go/src/runtime/mgcmark.go:1057 +0xa8 fp=0x7ffeefbff490 sp=0x7ffeefbff430 pc=0x1018618
runtime.markrootBlock(0x10bd640, 0x1b410, 0x1212869, 0xc000021270, 0x0)
	/Users/mr/gotip/src/github.com/golang/go/src/runtime/mgcmark.go:251 +0x9c fp=0x7ffeefbff4c8 sp=0x7ffeefbff490 pc=0x1016a3c
runtime.markroot(0xc000021270, 0x3)
	/Users/mr/gotip/src/github.com/golang/go/src/runtime/mgcmark.go:166 +0x1b1 fp=0x7ffeefbff548 sp=0x7ffeefbff4c8 pc=0x10167e1
runtime.gcDrainN(0xc000021270, 0x10000, 0x0)
	/Users/mr/gotip/src/github.com/golang/go/src/runtime/mgcmark.go:1006 +0xff fp=0x7ffeefbff578 sp=0x7ffeefbff548 pc=0x101843f
runtime.gcAssistAlloc1(0xc000000180, 0x10000)
	/Users/mr/gotip/src/github.com/golang/go/src/runtime/mgcmark.go:512 +0xf4 fp=0x7ffeefbff5c8 sp=0x7ffeefbff578 pc=0x1017174
runtime.gcAssistAlloc.func1()
	/Users/mr/gotip/src/github.com/golang/go/src/runtime/mgcmark.go:423 +0x33 fp=0x7ffeefbff5e8 sp=0x7ffeefbff5c8 pc=0x1044a93
runtime.systemstack(0x0)
	/Users/mr/gotip/src/github.com/golang/go/src/runtime/asm_amd64.s:351 +0x66 fp=0x7ffeefbff5f0 sp=0x7ffeefbff5e8 pc=0x1046686
runtime.mstart()
	/Users/mr/gotip/src/github.com/golang/go/src/runtime/proc.go:1153 fp=0x7ffeefbff5f8 sp=0x7ffeefbff5f0 pc=0x1027390

goroutine 1 [GC assist marking]:
runtime.systemstack_switch()
	/Users/mr/gotip/src/github.com/golang/go/src/runtime/asm_amd64.s:311 fp=0xc0003629f0 sp=0xc0003629e8 pc=0x1046610
runtime.gcAssistAlloc(0xc000000180)
	/Users/mr/gotip/src/github.com/golang/go/src/runtime/mgcmark.go:422 +0x15c fp=0xc000362a50 sp=0xc0003629f0 pc=0x1016f0c
runtime.mallocgc(0x90, 0x10632e0, 0x1c01, 0xc0000e6000)
	/Users/mr/gotip/src/github.com/golang/go/src/runtime/malloc.go:843 +0x8d6 fp=0xc000362af0 sp=0xc000362a50 pc=0x100a0d6
runtime.newobject(...)
	/Users/mr/gotip/src/github.com/golang/go/src/runtime/malloc.go:1068
runtime.(*hmap).newoverflow(0xc000362c48, 0x105bec0, 0xc0016eca30, 0xc0000e6000)
	/Users/mr/gotip/src/github.com/golang/go/src/runtime/map.go:264 +0x2b1 fp=0xc000362b50 sp=0xc000362af0 pc=0x100ade1
runtime.mapassign_fast64(0x105bec0, 0xc000362c48, 0x5c1b3, 0xc00135eb60)
	/Users/mr/gotip/src/github.com/golang/go/src/runtime/map_fast64.go:162 +0x207 fp=0xc000362b90 sp=0xc000362b50 pc=0x100d197
main.allocstuff()
	/tmp/e/f/a.go:31 +0xad fp=0xc000362c88 sp=0xc000362b90 pc=0x104e30d
main.main()
	/tmp/e/f/a.go:38 +0x9b fp=0xc000362f98 sp=0xc000362c88 pc=0x104e3db
runtime.main()
	/Users/mr/gotip/src/github.com/golang/go/src/runtime/proc.go:200 +0x204 fp=0xc000362fe0 sp=0xc000362f98 pc=0x1024934
runtime.goexit()
	/Users/mr/gotip/src/github.com/golang/go/src/runtime/asm_amd64.s:1337 +0x1 fp=0xc000362fe8 sp=0xc000362fe0 pc=0x1048541

I've tried making many small variations to the reproducer but they've all stopped reproducing after the change:

  • Size of the Z buffer from 256 to either 128 or 512
  • Changing type in allocstuff map to map[int]int32 or map[int32]int
  • Presizing the map in allocstuff withm := make(map[int]int, 1000000)
  • Assigning saved = m at the end of allocstuff
  • Removing one of the unused Z parameters from the h function

So it looks like there are very specific circumstances required to reproduce this crash.

@AlekSi
Copy link
Contributor

AlekSi commented Dec 3, 2018

I bisected the latest reproducer from
#29000 (comment) to commit 21656d0 by @randall77. However, that may be the different issue from the one observed by OP since it seems to be macOS-specific, and also a new feature in 1.11.

@AlekSi
Copy link
Contributor

AlekSi commented Dec 3, 2018

Reproducer from #29000 (comment) crashes all versions of Go up 1.7. And I can't test 1.6.4 since it can't be compiled on Mojave.
Script for git bisect run is there: https://github.com/AlekSi/git-bisect-run

@dgryski
Copy link
Contributor

dgryski commented Dec 3, 2018

My attempt at bisecting landed on 8607b2e . I wonder if the fact that it's not 100% reproducible is affecting the bisecting logic?

#!/bin/bash

export GOROOT_BOOTSTRAP=/usr/local/go

# the build command
(cd src && ./make.bash) || exit 125

# the script to run to test failure or not
set -e
(cd  /Users/dgryski/go/src/github.com/dgryski/bug && go build && ./bug)
exit 0

@josharian
Copy link
Contributor

I wonder if the fact that it's not 100% reproducible is affecting the bisecting logic?

Definitely. Probably need to loop a fair number of times before calling a commit good.

@josharian
Copy link
Contributor

josharian commented Dec 3, 2018

And if this is sensitive to stack layout or optimizations or other fiddly toolchain details, looping might not even help. Might want to try also check as many different reproducers as you can.

If that doesn't help, I would also consider focusing on changes that touch runtime/map*. We do lots of sketchy stuff there around GC and overflow buckets, and they have evolved non-trivially on every release.

@dgryski
Copy link
Contributor

dgryski commented Dec 3, 2018

Updating to try 20 runs before failing also points to 21656d0 ; the previous commit didn't fail at 200 runs.

@zeldovich
Copy link
Author

Two maybe-helpful comments:

  • If you're trying to bisect, use GOGC=1, since that makes the bug much more reproducible. I'm mentioning this because I didn't see GOGC=1 in @dgryski 's bisect script above.

  • I don't think the bug is specific to maps. The role of allocstuff() in the test case is to just force lots of allocations so that a GC cycle happens during the execution of allocstuff(). Replacing it with the following map-free variant still reproduces the bug for me, suggesting that maps aren't to blame:

func allocstuff() {
	m := make([]byte, 0)
	for i := 0; i < 1000000; i++ {
		m = append(m, 1)
	}
}

@dgryski
Copy link
Contributor

dgryski commented Dec 3, 2018

Yes, my updated bisect script used

(cd  /Users/dgryski/go/src/github.com/dgryski/bug && go build && for i in $(seq 20);  do GOGC=1 ./bug; done )

as the check line.

@mknyszek
Copy link
Contributor

mknyszek commented Dec 4, 2018

I'm able to reproduce with @zeldovich's example which imports "net", haven't been able to with newer ones.

Looking a bit closer (and also looking at the above stack traces) the program is very consistently crashing when trying to mark in the GC following from a BSS value (an uninitialized global), and the only such value in this program is saved. The object pointed to from saved has its span recycled, sometimes multiple times. I was able to confirm this by tracing span allocations and looking at what happens to the span the object supposedly lives in (using https://go-review.googlesource.com/c/go/+/23432).

The pointer which gets written into saved does seem to refer to a Z object. I wrote in some data and then checked with gdb. What's weird though is its pointer value doesn't seem to correspond to any span of the right size class, throughout the entire span trace. You'd think that a Z, having nothing but a 256-byte array would just be 256 bytes. Instead I often see it in spans with class ((0) large, scan) or (10, noscan) which would cover the address of that object. I can't even find a span with the right size class (17, noscan) which is anywhere near the reported address of the object.

This is all very bizarre. I'll keep investigating tomorrow and look into where exactly this object is allocated, which might help to answer some questions.

@mknyszek mknyszek self-assigned this Dec 4, 2018
@dgryski
Copy link
Contributor

dgryski commented Dec 4, 2018

Also odd: running the latest repro under delve changes it enough that for me it never crashes.

@grodranlorth
Copy link

There seems to be a bug with escape analysis, which concludes that the Z written to "saved" does not escape. Thus a pointer to a stack-allocated Z is written to "saved", a subsequent GC will shrink/free the stack, and the GC then observes a pointer to an unallocated span and panics.

Using -gcflags="-m -m" supports this theory: the compiler concludes that the written Z does not escape. Without the recursive, dead-code call to f() in h(), the compiler correctly realizes that the Z escapes to the heap. Furthermore, the panic seems to go away when using GODEBUG="gcshrinkstackoff=1", presumably because the GC no longer finds a pointer to a free span.

@mknyszek
Copy link
Contributor

mknyszek commented Dec 4, 2018

Oh yeah, good catch. It explains why the pointer doesn't seem to be in any size-segregated span.

CC: @dr2chase @cherrymui

@mknyszek mknyszek changed the title runtime: heap or spans corruption cmd/compile: value assigned to global fails to escape Dec 4, 2018
@cherrymui
Copy link
Member

Interesting bug. It seems to need both

  • seemingly recursive
  • blank identifier
package p

var sink interface{}

//go:noinline
func f(_ int, x interface{}) {
	sink = x
	return
	g()
}

func g() {
	x := 1
	f(2, x)
}
$ go tool compile -m e2.go
e2.go:6:15: leaking param: x
e2.go:14:4: g x does not escape

The code handling recursive functions are a lot more interesting. I'll take a careful look.

@cherrymui
Copy link
Member

cherrymui commented Dec 4, 2018

The problem is that when analyzing the call, it iterates the formal parameters using fn.Name.Defn.Func.Dcl, which does not include unnamed or blank parameters. As a consequence, it sees mismatched formal and actual parameters.

@gopherbot
Copy link

Change https://golang.org/cl/152617 mentions this issue: cmd/compile: fix unnamed parameter handling in escape analysis

@golang golang locked and limited conversation to collaborators Dec 4, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
FrozenDueToAge NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. release-blocker
Projects
None yet
Development

No branches or pull requests