Skip to content

Commit 8da96a4

Browse files
committed
fix parsing go1.23 stack traces
Go 1.21 changed how the runtime prints deep stacks: golang/go@9eba17f fixes #90
1 parent 24a5cf9 commit 8da96a4

File tree

5 files changed

+31
-9
lines changed

5 files changed

+31
-9
lines changed

.github/workflows/test.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ jobs:
2020
matrix:
2121
os: [ubuntu-latest, macos-latest, windows-latest]
2222
# Do not forget to bump every 6 months!
23-
gover: ["1.20"]
23+
gover: ["1.23"]
2424
env:
2525
PYTHONDONTWRITEBYTECODE: x
2626
steps:
@@ -265,7 +265,7 @@ jobs:
265265
matrix:
266266
os: [ubuntu-latest]
267267
# Do not forget to bump every 6 months!
268-
gover: ["1.20"]
268+
gover: ["1.23"]
269269
permissions:
270270
security-events: write
271271
steps:

stack/context.go

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -252,7 +252,6 @@ const pathSeparator = string(filepath.Separator)
252252

253253
var (
254254
lockedToThread = []byte("locked to thread")
255-
framesElided = []byte("...additional frames elided...")
256255
// gotRaceHeader1, done
257256
raceHeaderFooter = []byte("==================")
258257
// gotRaceHeader2
@@ -270,7 +269,7 @@ var (
270269
// These are effectively constants.
271270
var (
272271
// gotRoutineHeader
273-
reRoutineHeader = regexp.MustCompile("^([ \t]*)goroutine (\\d+) \\[([^\\]]+)\\]\\:$")
272+
reRoutineHeader = regexp.MustCompile("^([ \t]*)goroutine (\\d+)(?: gp=[^ ]+ m=[^ ]+(?: mp=[^ ]+)?)? \\[([^\\]]+)\\]\\:$")
274273
reMinutes = regexp.MustCompile(`^(\d+) minutes$`)
275274

276275
// gotUnavail
@@ -450,6 +449,18 @@ type scanningState struct {
450449
goroutineIndex int
451450
}
452451

452+
func isFramesElidedLine(line []byte) bool {
453+
// before go1.21:
454+
// ...additional frames elided...
455+
//
456+
// go1.21 and newer:
457+
// print("...", elide, " frames elided...\n")
458+
framesElided := []byte("...additional frames elided...")
459+
return bytes.Equal(line, framesElided) ||
460+
bytes.HasPrefix(line, []byte("...")) &&
461+
bytes.HasSuffix(line, []byte(" frames elided..."))
462+
}
463+
453464
// scan scans one line, updates goroutines and move to the next state.
454465
//
455466
// Returns true if the line was processed and thus should not be printed out.
@@ -605,7 +616,7 @@ func (s *scanningState) scan(line []byte) (bool, error) {
605616
s.state = gotCreated
606617
return true, nil
607618
}
608-
if bytes.Equal(trimmed, framesElided) {
619+
if isFramesElidedLine(trimmed) {
609620
cur.Stack.Elided = true
610621
// TODO(maruel): New state.
611622
return true, nil

stack/context_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2350,7 +2350,7 @@ func identifyPanicwebSignature(t *testing.T, b *Bucket, pwebDir string) panicweb
23502350
t.Fatal("expected Locked")
23512351
}
23522352
// This is a change detector on internal/main.go.
2353-
want := Stack{Calls: []Call{newCallLocal("main.main", Args{}, pathJoin(pwebDir, "main.go"), 145)}}
2353+
want := Stack{Calls: []Call{newCallLocal("main.main in goroutine 1", Args{}, pathJoin(pwebDir, "main.go"), 145)}}
23542354
compareStacks(t, &b.Signature.CreatedBy, &want)
23552355
for i := range b.Signature.Stack.Calls {
23562356
if strings.HasPrefix(b.Signature.Stack.Calls[i].ImportPath, "github.com/mattn/go-colorable") {
@@ -2364,7 +2364,7 @@ func identifyPanicwebSignature(t *testing.T, b *Bucket, pwebDir string) panicweb
23642364
{
23652365
want := Stack{
23662366
Calls: []Call{
2367-
newCallLocal("main.main", Args{}, pathJoin(pwebDir, "main.go"), 63),
2367+
newCallLocal("main.main in goroutine 1", Args{}, pathJoin(pwebDir, "main.go"), 63),
23682368
},
23692369
}
23702370
zapStacks(t, &want, &b.CreatedBy)

stack/source_test.go

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -494,9 +494,12 @@ func TestAugment(t *testing.T) {
494494
"main.f",
495495
Args{
496496
Values: []Arg{{IsAggregate: true, Fields: Args{
497-
Values: []Arg{{Value: pointer, IsPtr: true}, {Value: 3}},
497+
Values: []Arg{
498+
{Value: pointer, IsPtr: true},
499+
{Value: pointer, IsPtr: true},
500+
},
498501
}}},
499-
Processed: []string{"error{0x2fffffff, 0x3}"},
502+
Processed: []string{"error{0x2fffffff, 0x2fffffff}"},
500503
},
501504
"/root/main.go",
502505
7),

stack/stack.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,14 @@ func (f *Func) Init(raw string) error {
7979
f.ImportPath = f.Complete[:endPkg]
8080
}
8181
f.Name = f.Complete[endPkg+1:]
82+
if idx := strings.LastIndexByte(f.Name, ' '); idx > -1 {
83+
cut := f.Name[:idx]
84+
// TODO(go1.20): switch to strings.CutSuffix
85+
const inGoroutineSuffix = " in goroutine"
86+
if strings.HasSuffix(cut, inGoroutineSuffix) {
87+
f.Name = strings.TrimSuffix(cut, inGoroutineSuffix)
88+
}
89+
}
8290
f.DirName = f.ImportPath
8391
if i := strings.LastIndexByte(f.DirName, '/'); i != -1 {
8492
f.DirName = f.DirName[i+1:]

0 commit comments

Comments
 (0)