Commit 3193c71c authored by Austin Clements's avatar Austin Clements

runtime: fix bad pointer with 0 stack barriers

Currently, if the number of stack barriers for a stack is 0, we'll
create a zero-length slice that points just past the end of the stack
allocation. This bad pointer causes GC panics.

Fix this by creating a nil slice if the stack barrier count is 0.

In practice, the only way this can happen is if
GODEBUG=gcstackbarrieroff=1 is set because even the minimum size stack
reserves space for two stack barriers.

Change-Id: I3527c9a504c445b64b81170ee285a28594e7983d
Reviewed-on: https://go-review.googlesource.com/31762Reviewed-by: 's avatarRick Hudson <rlh@golang.org>
parent d1cc8347
...@@ -335,6 +335,7 @@ func stackalloc(n uint32) (stack, []stkbar) { ...@@ -335,6 +335,7 @@ func stackalloc(n uint32) (stack, []stkbar) {
// Compute the size of stack barrier array. // Compute the size of stack barrier array.
maxstkbar := gcMaxStackBarriers(int(n)) maxstkbar := gcMaxStackBarriers(int(n))
nstkbar := unsafe.Sizeof(stkbar{}) * uintptr(maxstkbar) nstkbar := unsafe.Sizeof(stkbar{}) * uintptr(maxstkbar)
var stkbarSlice slice
if debug.efence != 0 || stackFromSystem != 0 { if debug.efence != 0 || stackFromSystem != 0 {
v := sysAlloc(round(uintptr(n), _PageSize), &memstats.stacks_sys) v := sysAlloc(round(uintptr(n), _PageSize), &memstats.stacks_sys)
...@@ -342,7 +343,9 @@ func stackalloc(n uint32) (stack, []stkbar) { ...@@ -342,7 +343,9 @@ func stackalloc(n uint32) (stack, []stkbar) {
throw("out of memory (stackalloc)") throw("out of memory (stackalloc)")
} }
top := uintptr(n) - nstkbar top := uintptr(n) - nstkbar
stkbarSlice := slice{add(v, top), 0, maxstkbar} if maxstkbar != 0 {
stkbarSlice = slice{add(v, top), 0, maxstkbar}
}
return stack{uintptr(v), uintptr(v) + top}, *(*[]stkbar)(unsafe.Pointer(&stkbarSlice)) return stack{uintptr(v), uintptr(v) + top}, *(*[]stkbar)(unsafe.Pointer(&stkbarSlice))
} }
...@@ -410,7 +413,9 @@ func stackalloc(n uint32) (stack, []stkbar) { ...@@ -410,7 +413,9 @@ func stackalloc(n uint32) (stack, []stkbar) {
print(" allocated ", v, "\n") print(" allocated ", v, "\n")
} }
top := uintptr(n) - nstkbar top := uintptr(n) - nstkbar
stkbarSlice := slice{add(v, top), 0, maxstkbar} if maxstkbar != 0 {
stkbarSlice = slice{add(v, top), 0, maxstkbar}
}
return stack{uintptr(v), uintptr(v) + top}, *(*[]stkbar)(unsafe.Pointer(&stkbarSlice)) return stack{uintptr(v), uintptr(v) + top}, *(*[]stkbar)(unsafe.Pointer(&stkbarSlice))
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment