Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions src/cmd/trace/pprof.go
Original file line number Diff line number Diff line change
Expand Up @@ -319,10 +319,15 @@ func (m *stackMap) profile() []traceviewer.ProfileRecord {

// pcsForStack extracts the first pprofMaxStack PCs from stack into pcs.
func pcsForStack(stack trace.Stack, pcs *[pprofMaxStack]uint64) {
for i, frame := range slices.Collect(stack.Frames()) {
pcs[i] = frame.PC
fillPCs(slices.Collect(stack.Frames()), pcs)
}

// fillPCs writes frame PCs into pcs, stopping at len(pcs).
func fillPCs(frames []trace.StackFrame, pcs *[pprofMaxStack]uint64) {
for i, frame := range frames {
if i >= len(pcs) {
break
}
pcs[i] = frame.PC
}
}
25 changes: 25 additions & 0 deletions src/cmd/trace/pprof_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (
"testing/synctest"
"time"

itrace "internal/trace"
"internal/trace/testtrace"
)

Expand Down Expand Up @@ -81,6 +82,30 @@ func TestSyscallProfile74850(t *testing.T) {
}
}

// Regression test: fillPCs (used by pcsForStack) must not panic when the
// number of frames exceeds pprofMaxStack (128). Before the fix, pcs[i] was
// written before checking i >= len(pcs), causing an index-out-of-range panic.
func TestFillPCsOverflow(t *testing.T) {
var pcs [pprofMaxStack]uint64

// Build a slice of frames larger than pprofMaxStack.
n := pprofMaxStack + 10
frames := make([]itrace.StackFrame, n)
for i := range frames {
frames[i].PC = uint64(0x1000 + i)
}

// This must not panic.
fillPCs(frames, &pcs)

// Verify the first pprofMaxStack entries were written correctly.
for i := 0; i < pprofMaxStack; i++ {
if pcs[i] != uint64(0x1000+i) {
t.Errorf("pcs[%d] = %#x, want %#x", i, pcs[i], 0x1000+i)
}
}
}

func stat(t *testing.T) {
_, err := os.Stat(".")
if err != nil {
Expand Down