diff --git a/src/runtime/pprof/proto.go b/src/runtime/pprof/proto.go index f0769935ae..085027cd98 100644 --- a/src/runtime/pprof/proto.go +++ b/src/runtime/pprof/proto.go @@ -246,9 +246,10 @@ type locInfo struct { // https://github.com/golang/go/blob/d6f2f833c93a41ec1c68e49804b8387a06b131c5/src/runtime/traceback.go#L347-L368 pcs []uintptr - // results of allFrames call for this PC - frames []runtime.Frame - symbolizeResult symbolizeFlag + // firstPCFrames and firstPCSymbolizeResult hold the results of the + // allFrames call for the first (leaf-most) PC this locInfo represents + firstPCFrames []runtime.Frame + firstPCSymbolizeResult symbolizeFlag } // newProfileBuilder returns a new profileBuilder. @@ -416,7 +417,7 @@ func (b *profileBuilder) appendLocsForStack(locs []uint64, stk []uintptr) (newLo // stack by trying to add it to the inlining deck before assuming // that the deck is complete. if len(b.deck.pcs) > 0 { - if added := b.deck.tryAdd(addr, l.frames, l.symbolizeResult); added { + if added := b.deck.tryAdd(addr, l.firstPCFrames, l.firstPCSymbolizeResult); added { stk = stk[1:] continue } @@ -520,12 +521,21 @@ type pcDeck struct { pcs []uintptr frames []runtime.Frame symbolizeResult symbolizeFlag + + // firstPCFrames indicates the number of frames associated with the first + // (leaf-most) PC in the deck + firstPCFrames int + // firstPCSymbolizeResult holds the results of the allFrames call for the + // first (leaf-most) PC in the deck + firstPCSymbolizeResult symbolizeFlag } func (d *pcDeck) reset() { d.pcs = d.pcs[:0] d.frames = d.frames[:0] d.symbolizeResult = 0 + d.firstPCFrames = 0 + d.firstPCSymbolizeResult = 0 } // tryAdd tries to add the pc and Frames expanded from it (most likely one, @@ -554,6 +564,10 @@ func (d *pcDeck) tryAdd(pc uintptr, frames []runtime.Frame, symbolizeResult symb d.pcs = append(d.pcs, pc) d.frames = append(d.frames, frames...) d.symbolizeResult |= symbolizeResult + if len(d.pcs) == 1 { + d.firstPCFrames = len(d.frames) + d.firstPCSymbolizeResult = symbolizeResult + } return true } @@ -581,10 +595,10 @@ func (b *profileBuilder) emitLocation() uint64 { id := uint64(len(b.locs)) + 1 b.locs[addr] = locInfo{ - id: id, - pcs: append([]uintptr{}, b.deck.pcs...), - symbolizeResult: b.deck.symbolizeResult, - frames: append([]runtime.Frame{}, b.deck.frames...), + id: id, + pcs: append([]uintptr{}, b.deck.pcs...), + firstPCSymbolizeResult: b.deck.firstPCSymbolizeResult, + firstPCFrames: append([]runtime.Frame{}, b.deck.frames[:b.deck.firstPCFrames]...), } start := b.pb.startMessage()