1
0
mirror of https://github.com/golang/go synced 2024-09-28 22:24:29 -06:00

runtime: fix liveness issue in test-only getgcmask

getgcmask stops referencing the object passed to it sometime between
when the object is looked up and when the function returns. Notably,
this can happen while the GC mask is actively being produced, and thus
the GC might free the object.

This is easily reproducible by adding a runtime.GC call at just the
right place. Adding a KeepAlive on the heap-object path fixes it.

Fixes #64188.

Change-Id: I5ed4cae862fc780338b60d969fd7fbe896352ce4
Reviewed-on: https://go-review.googlesource.com/c/go/+/542716
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Cherry Mui <cherryyz@google.com>
This commit is contained in:
Michael Anthony Knyszek 2023-11-15 21:54:45 +00:00 committed by Michael Knyszek
parent 0011342590
commit 17eb0a2bac
2 changed files with 10 additions and 0 deletions

View File

@ -1078,6 +1078,11 @@ func getgcmask(ep any) (mask []byte) {
for len(mask) > 0 && mask[len(mask)-1] == 0 { for len(mask) > 0 && mask[len(mask)-1] == 0 {
mask = mask[:len(mask)-1] mask = mask[:len(mask)-1]
} }
// Make sure we keep ep alive. We may have stopped referencing
// ep's data pointer sometime before this point and it's possible
// for that memory to get freed.
KeepAlive(ep)
return return
} }

View File

@ -744,6 +744,11 @@ func getgcmask(ep any) (mask []byte) {
for len(mask) > 0 && mask[len(mask)-1] == 0 { for len(mask) > 0 && mask[len(mask)-1] == 0 {
mask = mask[:len(mask)-1] mask = mask[:len(mask)-1]
} }
// Make sure we keep ep alive. We may have stopped referencing
// ep's data pointer sometime before this point and it's possible
// for that memory to get freed.
KeepAlive(ep)
return return
} }