diff options
| author | Keith Randall <khr@google.com> | 2019-07-29 12:51:19 -0700 |
|---|---|---|
| committer | Keith Randall <khr@golang.org> | 2019-07-29 21:07:49 +0000 |
| commit | 01d137262a713b308c4308ed5b26636895e68d89 (patch) | |
| tree | e0a3502cbee9aabcc9060f2230e1f941b19eb294 /src/runtime/malloc.go | |
| parent | 7b8234b48fb66e9932abfbbaa24307480682e9b9 (diff) | |
| download | go-01d137262a713b308c4308ed5b26636895e68d89.tar.xz | |
runtime: use uintptr instead of int32 for counting to next heap profile sample
Overflow of the comparison caused very large (>=1<<32) allocations to
sometimes not get sampled at all. Use uintptr so the comparison will
never overflow.
Fixes #33342
Tested on the example in 33342. I don't want to check a test in that
needs that much memory, however.
Change-Id: I51fe77a9117affed8094da93c0bc5f445ac2d3d3
Reviewed-on: https://go-review.googlesource.com/c/go/+/188017
Run-TryBot: Keith Randall <khr@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Austin Clements <austin@google.com>
Diffstat (limited to 'src/runtime/malloc.go')
| -rw-r--r-- | src/runtime/malloc.go | 12 |
1 files changed, 6 insertions, 6 deletions
diff --git a/src/runtime/malloc.go b/src/runtime/malloc.go index 8ad7035d94..5a21e80e18 100644 --- a/src/runtime/malloc.go +++ b/src/runtime/malloc.go @@ -1075,8 +1075,8 @@ func mallocgc(size uintptr, typ *_type, needzero bool) unsafe.Pointer { } if rate := MemProfileRate; rate > 0 { - if rate != 1 && int32(size) < c.next_sample { - c.next_sample -= int32(size) + if rate != 1 && size < c.next_sample { + c.next_sample -= size } else { mp := acquirem() profilealloc(mp, x, size) @@ -1170,7 +1170,7 @@ func profilealloc(mp *m, x unsafe.Pointer, size uintptr) { // processes, the distance between two samples follows the exponential // distribution (exp(MemProfileRate)), so the best return value is a random // number taken from an exponential distribution whose mean is MemProfileRate. -func nextSample() int32 { +func nextSample() uintptr { if GOOS == "plan9" { // Plan 9 doesn't support floating point in note handler. if g := getg(); g == g.m.gsignal { @@ -1178,7 +1178,7 @@ func nextSample() int32 { } } - return fastexprand(MemProfileRate) + return uintptr(fastexprand(MemProfileRate)) } // fastexprand returns a random number from an exponential distribution with @@ -1213,14 +1213,14 @@ func fastexprand(mean int) int32 { // nextSampleNoFP is similar to nextSample, but uses older, // simpler code to avoid floating point. -func nextSampleNoFP() int32 { +func nextSampleNoFP() uintptr { // Set first allocation sample size. rate := MemProfileRate if rate > 0x3fffffff { // make 2*rate not overflow rate = 0x3fffffff } if rate != 0 { - return int32(fastrand() % uint32(2*rate)) + return uintptr(fastrand() % uint32(2*rate)) } return 0 } |
