Skip to content

Commit e31e35a

Browse files
committed
runtime: reset gcscanvalid and gcworkdone when GODEBUG=gctrace=2
When GODEBUG=gctrace=2 two gcs are preformed. During the first gc the stack scan sets the g's gcscanvalid and gcworkdone flags to true indicating that the stacks have to be scanned and do not need to be rescanned. These need to be reset to false for the second GC so the stacks are rescanned, otherwise if the only pointer to an object is on the stack it will not be discovered and the object will be freed. Typically this will include the object that was just allocated in the mallocgc call that initiated the GC. Change-Id: Ic25163f4689905fd810c90abfca777324005c02f Reviewed-on: https://go-review.googlesource.com/5861 Reviewed-by: Russ Cox <[email protected]>
1 parent 42289a4 commit e31e35a

File tree

1 file changed

+9
-1
lines changed

1 file changed

+9
-1
lines changed

Diff for: src/runtime/mgc.go

+9-1
Original file line numberDiff line numberDiff line change
@@ -339,7 +339,7 @@ func gc(mode int) {
339339
})
340340
} else {
341341
// For non-concurrent GC (mode != gcBackgroundMode)
342-
// g stack have not been scanned so set gcscanvalid
342+
// The g stacks have not been scanned so set gcscanvalid
343343
// such that mark termination scans all stacks.
344344
// No races here since we are in a STW phase.
345345
for _, gp := range allgs {
@@ -381,6 +381,14 @@ func gc(mode int) {
381381

382382
if debug.gctrace > 1 {
383383
startTime = nanotime()
384+
// The g stacks have been scanned so
385+
// they have gcscanvalid==true and gcworkdone==true.
386+
// Reset these so that all stacks will be rescanned.
387+
// No races here since we are in a STW phase.
388+
for _, gp := range allgs {
389+
gp.gcworkdone = false // set to true in gcphasework
390+
gp.gcscanvalid = false // stack has not been scanned
391+
}
384392
finishsweep_m()
385393
gcMark(startTime)
386394
gcSweep(mode)

0 commit comments

Comments
 (0)