for _, k := range keys {
values[0] = int64(count[k])
locs = locs[:0]
- for i, addr := range p.Stack(index[k]) {
- if false && i > 0 { // TODO: why disabled?
- addr--
- }
+ for _, addr := range p.Stack(index[k]) {
+ // For count profiles, all stack addresses are
+ // return PCs. Adjust them to be call PCs for
+ // locForPC.
+ addr--
locs = append(locs, b.locForPC(addr))
}
b.pbSample(values, locs, nil)
}
// locForPC returns the location ID for addr.
+// addr must be a call address (not a return address).
// It may emit to b.pb, so there must be no message encoding in progress.
func (b *profileBuilder) locForPC(addr uintptr) uint64 {
id := uint64(b.locs[addr])
locs = locs[:0]
hideRuntime := true
for tries := 0; tries < 2; tries++ {
- for i, addr := range r.Stack() {
- if false && i > 0 { // TODO: why disabled?
- addr--
- }
+ for _, addr := range r.Stack() {
+ // For heap profiles, all stack
+ // addresses are return PCs. Adjust
+ // them to be call PCs for locForPC.
+ addr--
if hideRuntime {
if f := runtime.FuncForPC(addr); f != nil && strings.HasPrefix(f.Name(), "runtime.") {
continue
addr1, addr2, map1, map2 := testPCs(t)
var buf bytes.Buffer
- a1, a2 := uintptr(addr1), uintptr(addr2)
+ // MemProfileRecord stacks are return PCs, so add one to the
+ // addresses recorded in the "profile". The proto profile
+ // locations are call PCs, so conversion will subtract one
+ // from these and get back to addr1 and addr2.
+ a1, a2 := uintptr(addr1)+1, uintptr(addr2)+1
rate := int64(512 * 1024)
rec := []runtime.MemProfileRecord{
{AllocBytes: 4096, FreeBytes: 1024, AllocObjects: 4, FreeObjects: 1, Stack0: [32]uintptr{a1, a2}},