mirror of
https://github.com/golang/go
synced 2024-11-23 15:30:05 -07:00
26ad5d4ff0
The inputs to a function are marked live at all times in the liveness bitmaps, so that the garbage collector will not free the things they point at and reuse the pointers, so that the pointers shown in stack traces are guaranteed not to have been recycled. Unfortunately, no one told the register optimizer that the inputs need to be preserved at all call sites. If a function is done with a particular input value, the optimizer will stop preserving it across calls. For single-word values this just means that the value recorded might be stale. For multi-word values like slices, the value recorded could be only partially stale: it can happen that, say, the cap was updated but not the len, or that the len was updated but not the base pointer. Either of these possibilities (and others) would make the garbage collector misinterpret memory, leading to memory corruption. This came up in a real program, in which the garbage collector's 'slice len ≤ slice cap' check caught the inconsistency. Fixes #7944. LGTM=iant R=golang-codereviews, iant CC=golang-codereviews, khr https://golang.org/cl/100370045
41 lines
559 B
Go
41 lines
559 B
Go
// run
|
|
|
|
// Copyright 2014 The Go Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style
|
|
// license that can be found in the LICENSE file.
|
|
|
|
// Issue 7944:
|
|
// Liveness bitmaps said b was live at call to g,
|
|
// but no one told the register optimizer.
|
|
|
|
package main
|
|
|
|
import "runtime"
|
|
|
|
func f(b []byte) {
|
|
for len(b) > 0 {
|
|
n := len(b)
|
|
n = f1(n)
|
|
f2(b[n:])
|
|
b = b[n:]
|
|
}
|
|
g()
|
|
}
|
|
|
|
func f1(n int) int {
|
|
runtime.GC()
|
|
return n
|
|
}
|
|
|
|
func f2(b []byte) {
|
|
runtime.GC()
|
|
}
|
|
|
|
func g() {
|
|
runtime.GC()
|
|
}
|
|
|
|
func main() {
|
|
f(make([]byte, 100))
|
|
}
|