Skip to content

Commit 4033066

Browse files
authored
Merge 599d78e into a3a584e
2 parents a3a584e + 599d78e commit 4033066

File tree

3 files changed

+24
-2
lines changed

3 files changed

+24
-2
lines changed

src/internal/profilerecord/profilerecord.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ package profilerecord
1010

1111
type StackRecord struct {
1212
Stack []uintptr
13+
GoID uint64
1314
}
1415

1516
type MemProfileRecord struct {

src/runtime/mprof.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1009,6 +1009,7 @@ func mutexevent(cycles int64, skip int) {
10091009
// A StackRecord describes a single execution stack.
10101010
type StackRecord struct {
10111011
Stack0 [32]uintptr // stack trace for this record; ends at first 0 entry
1012+
goid uint64 // Goroutine ID for the first record (or 0 if undefined by the struct creator).
10121013
}
10131014

10141015
// Stack returns the stack trace associated with the record,
@@ -1022,6 +1023,11 @@ func (r *StackRecord) Stack() []uintptr {
10221023
return r.Stack0[0:]
10231024
}
10241025

1026+
// GoID returns an identifier for the Goroutine this stack was captured for, or zero if undefined.
1027+
func (r *StackRecord) GoID() uint64 {
1028+
return r.goid
1029+
}
1030+
10251031
// MemProfileRate controls the fraction of memory allocations
10261032
// that are recorded and reported in the memory profile.
10271033
// The profiler aims to sample an average of
@@ -1707,6 +1713,7 @@ func GoroutineProfile(p []StackRecord) (n int, ok bool) {
17071713
}
17081714
for i, mr := range records[0:n] {
17091715
copy(p[i].Stack0[:], mr.Stack)
1716+
p[i].goid = mr.GoID
17101717
}
17111718
return
17121719
}
@@ -1735,6 +1742,7 @@ func saveg(pc, sp uintptr, gp *g, r *profilerecord.StackRecord, pcbuf []uintptr)
17351742
n := tracebackPCs(&u, 0, pcbuf)
17361743
r.Stack = make([]uintptr, n)
17371744
copy(r.Stack, pcbuf)
1745+
r.GoID = gp.goid
17381746
}
17391747

17401748
// Stack formats a stack trace of the calling goroutine into buf

src/runtime/runtime_test.go

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -344,17 +344,19 @@ func TestAppendSliceGrowth(t *testing.T) {
344344
}
345345
}
346346

347-
func TestGoroutineProfileTrivial(t *testing.T) {
347+
func TestGoroutineProfile(t *testing.T) {
348348
// Calling GoroutineProfile twice in a row should find the same number of goroutines,
349349
// but it's possible there are goroutines just about to exit, so we might end up
350350
// with fewer in the second call. Try a few times; it should converge once those
351351
// zombies are gone.
352+
var records []StackRecord
352353
for i := 0; ; i++ {
353354
n1, ok := GoroutineProfile(nil) // should fail, there's at least 1 goroutine
354355
if n1 < 1 || ok {
355356
t.Fatalf("GoroutineProfile(nil) = %d, %v, want >0, false", n1, ok)
356357
}
357-
n2, ok := GoroutineProfile(make([]StackRecord, n1))
358+
records = make([]StackRecord, n1)
359+
n2, ok := GoroutineProfile(records)
358360
if n2 == n1 && ok {
359361
break
360362
}
@@ -363,6 +365,17 @@ func TestGoroutineProfileTrivial(t *testing.T) {
363365
t.Fatalf("GoroutineProfile not converging")
364366
}
365367
}
368+
if len(records) < 1 {
369+
t.Fatalf("GoroutineProfile hasn't collected any records")
370+
}
371+
for _, record := range records {
372+
if len(record.Stack()) < 1 {
373+
t.Fatalf("GoroutineProfile record is missing a stack trace")
374+
}
375+
if record.GoID() < 1 {
376+
t.Fatalf("GoroutineProfile record is missing a GoID")
377+
}
378+
}
366379
}
367380

368381
func BenchmarkGoroutineProfile(b *testing.B) {

0 commit comments

Comments
 (0)