go: runtime: Invalid garbage collection of structure pointers

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

$ go version 1.13.6

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

GO111MODULE=“” GOARCH=“amd64” GOBIN=“” GOCACHE=“/home/lcars/.cache/go-build” GOENV=“/home/lcars/.config/go/env” GOEXE=“” GOFLAGS=“” GOHOSTARCH=“amd64” GOHOSTOS=“linux” GONOPROXY=“” GONOSUMDB=“” GOOS=“linux” GOPATH=“/home/lcars/go” GOPRIVATE=“” GOPROXY=“https://proxy.golang.org,direct” GOROOT=“/usr/lib/go” GOSUMDB=“sum.golang.org” GOTMPDIR=“” GOTOOLDIR=“/usr/lib/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-build760597893=/tmp/go-build -gno-record-gcc-switches”

What did you do?

Run the example at https://play.golang.org/p/RIMIZDWEcZT

What did you expect to see?

I expect the code not to panic.

What did you see instead?

The code panic because GC scrapes struct instances which should be preserved.

Description

The code at https://play.golang.org/p/RIMIZDWEcZT uses an AlignmentBuffer structure to allow selection of an aligned offset over a []byte array for casting a structure. (This is used for bare metal code operation within TamaGo, however the identified issue is not specific to bare metal and/or TamaGo code as it is reproducible with standard Go).

The dTD struct holds two pointers to AlignmentBuffer instances, what is witnessed in the main function is that allocating an array of []*dTD results, without losing a reference to it, for the *AlignmentBuffer pointer contents to be scraped out by GC.

This is unexpected behaviour.

In order to workaround this we had to keep the two *AlignmentBuffer pointers outside the dTD struct, as this doesn’t trigger the issue.

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Reactions: 2
  • Comments: 27 (13 by maintainers)

Most upvoted comments

I’d just like to thanks again for the nice discussion here, which triggered restructuring our code to avoid all casting that might break in the future, we dramatically reduced the use of unsafe by performing all allocations for DMA purposes through a specific API and using encoding/binary as suggested:

https://github.com/f-secure-foundry/tamago/compare/ee270ccba8ff20d121e6f48d97e427e6e411cde0...c0e43968541b557c6c408bc7f43f898ebff7df83