Skip to content

Commit 8455a84

Browse files
randall77katiehockman
authored andcommitted
[release-branch.go1.11] runtime: don't scan go'd function args past length of ptr bitmap
Use the length of the bitmap to decide how much to pass to the write barrier, not the total length of the arguments. The test needs enough arguments so that two distinct bitmaps get interpreted as a single longer bitmap. Fixes #29565 Change-Id: I78f3f7f9ec89c2ad4678f0c52d3d3def9cac8e72 Reviewed-on: https://go-review.googlesource.com/c/156123 Run-TryBot: Keith Randall <[email protected]> TryBot-Result: Gobot Gobot <[email protected]> Reviewed-by: Austin Clements <[email protected]> Reviewed-on: https://go-review.googlesource.com/c/156359 Reviewed-by: Ian Lance Taylor <[email protected]>
1 parent 84f1e92 commit 8455a84

File tree

2 files changed

+54
-1
lines changed

2 files changed

+54
-1
lines changed

src/runtime/proc.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3374,7 +3374,7 @@ func newproc1(fn *funcval, argp *uint8, narg int32, callergp *g, callerpc uintpt
33743374
if stkmap.nbit > 0 {
33753375
// We're in the prologue, so it's always stack map index 0.
33763376
bv := stackmapdata(stkmap, 0)
3377-
bulkBarrierBitmap(spArg, spArg, uintptr(narg), 0, bv.bytedata)
3377+
bulkBarrierBitmap(spArg, spArg, uintptr(bv.n)*sys.PtrSize, 0, bv.bytedata)
33783378
}
33793379
}
33803380
}

test/fixedbugs/issue29362b.go

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
// run
2+
3+
// Copyright 2018 The Go Authors. All rights reserved.
4+
// Use of this source code is governed by a BSD-style
5+
// license that can be found in the LICENSE file.
6+
7+
// Verify that we don't consider a Go'd function's
8+
// arguments as pointers when they aren't.
9+
10+
package main
11+
12+
import (
13+
"unsafe"
14+
)
15+
16+
var badPtr uintptr
17+
18+
var sink []byte
19+
20+
func init() {
21+
// Allocate large enough to use largeAlloc.
22+
b := make([]byte, 1<<16-1)
23+
sink = b // force heap allocation
24+
// Any space between the object and the end of page is invalid to point to.
25+
badPtr = uintptr(unsafe.Pointer(&b[len(b)-1])) + 1
26+
}
27+
28+
var throttle = make(chan struct{}, 10)
29+
30+
// There are 2 arg bitmaps for this function, each with 2 bits.
31+
// In the first, p and q are both live, so that bitmap is 11.
32+
// In the second, only p is live, so that bitmap is 10.
33+
// Bitmaps are byte aligned, so if the first bitmap is interpreted as
34+
// extending across the entire argument area, we incorrectly concatenate
35+
// the bitmaps and end up using 110000001. That bad bitmap causes a6
36+
// to be considered a pointer.
37+
func noPointerArgs(p, q *byte, a0, a1, a2, a3, a4, a5, a6 uintptr) {
38+
sink = make([]byte, 4096)
39+
sinkptr = q
40+
<-throttle
41+
sinkptr = p
42+
}
43+
44+
var sinkptr *byte
45+
46+
func main() {
47+
const N = 1000
48+
for i := 0; i < N; i++ {
49+
throttle <- struct{}{}
50+
go noPointerArgs(nil, nil, badPtr, badPtr, badPtr, badPtr, badPtr, badPtr, badPtr)
51+
sink = make([]byte, 4096)
52+
}
53+
}

0 commit comments

Comments
 (0)