Skip to content

Commit f4c7a12

Browse files
committed
runtime: make module typemaps visible to the GC
The map[typeOff]*_type object is created at run time and stored in the moduledata. The moduledata object is marked by the linker as SNOPTRDATA, so the reference is ignored by the GC. Running misc/cgo/testplugin/test.bash with GOGC=1 will eventually collect the typemap and crash. This bug probably comes up in -linkshared binaries in Go 1.7. I don't know why we haven't seen a report about this yet. Fixes #17680 Change-Id: I0e9b5c006010e8edd51d9471651620ba665248d3 Reviewed-on: https://go-review.googlesource.com/32430 TryBot-Result: Gobot Gobot <[email protected]> Reviewed-by: Michael Hudson-Doyle <[email protected]> Reviewed-by: Ian Lance Taylor <[email protected]>
1 parent 9da7058 commit f4c7a12

File tree

2 files changed

+12
-1
lines changed

2 files changed

+12
-1
lines changed

src/runtime/symtab.go

+9
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,15 @@ type modulehash struct {
222222
runtimehash *string
223223
}
224224

225+
// pinnedTypemaps are the map[typeOff]*_type from the moduledata objects.
226+
//
227+
// These typemap objects are allocated at run time on the heap, but the
228+
// only direct reference to them is in the moduledata, created by the
229+
// linker and marked SNOPTRDATA so it is ignored by the GC.
230+
//
231+
// To make sure the map isn't collected, we keep a second reference here.
232+
var pinnedTypemaps []map[typeOff]*_type
233+
225234
var firstmoduledata moduledata // linker symbol
226235
var lastmoduledatap *moduledata // linker symbol
227236

src/runtime/type.go

+3-1
Original file line numberDiff line numberDiff line change
@@ -497,7 +497,9 @@ func typelinksinit() {
497497
// If any of this module's typelinks match a type from a
498498
// prior module, prefer that prior type by adding the offset
499499
// to this module's typemap.
500-
md.typemap = make(map[typeOff]*_type, len(md.typelinks))
500+
tm := make(map[typeOff]*_type, len(md.typelinks))
501+
pinnedTypemaps = append(pinnedTypemaps, tm)
502+
md.typemap = tm
501503
for _, tl := range md.typelinks {
502504
t := (*_type)(unsafe.Pointer(md.types + uintptr(tl)))
503505
for _, candidate := range typehash[t.hash] {

0 commit comments

Comments
 (0)