Skip to content

Commit c16396b

Browse files
committed
fix: trace parser in go1.21
1 parent 83727b6 commit c16396b

File tree

4 files changed

+66
-24
lines changed

4 files changed

+66
-24
lines changed

CHANGELOG.md

+6
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
# Changelog
22

3+
## Unreleased
4+
5+
### Bug fixes
6+
7+
- Fix trace function name parsing in profiler on go1.21+ ([#695](https://github.com/getsentry/sentry-go/pull/695))
8+
39
## 0.23.0
410

511
The Sentry SDK team is happy to announce the immediate availability of Sentry Go SDK v0.23.0.

internal/traceparser/parser.go

+9-1
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,15 @@ var createdByPrefix = []byte("created by ")
178178

179179
func (f *Frame) Func() []byte {
180180
if bytes.HasPrefix(f.line1, createdByPrefix) {
181-
return f.line1[len(createdByPrefix):]
181+
// Since go1.21, the line ends with " in goroutine X", saying which goroutine created this one.
182+
// We currently don't have use for that so just remove it.
183+
var line = f.line1[len(createdByPrefix):]
184+
var spaceAt = bytes.IndexByte(line, ' ')
185+
if spaceAt < 0 {
186+
return line
187+
} else {
188+
return line[:spaceAt]
189+
}
182190
}
183191

184192
var end = bytes.LastIndexByte(f.line1, '(')

internal/traceparser/parser_test.go

+50-23
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,39 @@ package traceparser
33
import (
44
"bytes"
55
"fmt"
6+
"runtime"
67
"strings"
78
"testing"
89

910
"github.com/stretchr/testify/require"
1011
)
1112

13+
func TestGenerateTrace(t *testing.T) {
14+
stacks := make(chan string)
15+
go func() {
16+
var stacksBuffer = make([]byte, 1000)
17+
for {
18+
// Capture stacks for all existing goroutines.
19+
// Note: runtime.GoroutineProfile() would be better but we can't use it at the moment because
20+
// it doesn't give us `gid` for each routine, see https://github.com/golang/go/issues/59663
21+
n := runtime.Stack(stacksBuffer, true)
22+
23+
// If we couldn't read everything, increase the buffer and try again.
24+
if n >= len(stacksBuffer) {
25+
stacksBuffer = make([]byte, n*2)
26+
} else {
27+
stacks <- string(stacksBuffer[0:n])
28+
break
29+
}
30+
}
31+
}()
32+
33+
t.Log(<-stacks)
34+
35+
// Note: uncomment to show the output so you can update it manually in tests below.
36+
// t.Fail()
37+
}
38+
1239
func TestParseEmpty(t *testing.T) {
1340
var require = require.New(t)
1441

@@ -17,11 +44,11 @@ func TestParseEmpty(t *testing.T) {
1744
}
1845

1946
var tracetext = []byte(`
20-
goroutine 18 [running]:
21-
testing.(*M).startAlarm.func1()
22-
C:/Users/name/scoop/apps/go/current/src/testing/testing.go:2241 +0x3c5
23-
created by time.goFunc
24-
C:/Users/name/scoop/apps/go/current/src/time/sleep.go:176 +0x32
47+
goroutine 7 [running]:
48+
github.com/getsentry/sentry-go/internal/traceparser.TestGenerateTrace.func1()
49+
c:/dev/sentry-go/internal/traceparser/parser_test.go:23 +0x6c
50+
created by github.com/getsentry/sentry-go/internal/traceparser.TestGenerateTrace in goroutine 6
51+
c:/dev/sentry-go/internal/traceparser/parser_test.go:17 +0x7f
2552
2653
goroutine 1 [chan receive]:
2754
testing.(*T).Run(0xc00006f6c0, {0x672288?, 0x180fd3?}, 0x6b5f98)
@@ -78,10 +105,10 @@ func TestParse(t *testing.T) {
78105
i++
79106
}
80107

81-
checkTrace(18, `testing.(*M).startAlarm.func1()
82-
C:/Users/name/scoop/apps/go/current/src/testing/testing.go:2241 +0x3c5
83-
created by time.goFunc
84-
C:/Users/name/scoop/apps/go/current/src/time/sleep.go:176 +0x32`)
108+
checkTrace(7, `github.com/getsentry/sentry-go/internal/traceparser.TestGenerateTrace.func1()
109+
c:/dev/sentry-go/internal/traceparser/parser_test.go:23 +0x6c
110+
created by github.com/getsentry/sentry-go/internal/traceparser.TestGenerateTrace in goroutine 6
111+
c:/dev/sentry-go/internal/traceparser/parser_test.go:17 +0x7f`)
85112

86113
checkTrace(1, `testing.(*T).Run(0xc00006f6c0, {0x672288?, 0x180fd3?}, 0x6b5f98)
87114
C:/Users/name/scoop/apps/go/current/src/testing/testing.go:1630 +0x405
@@ -144,13 +171,13 @@ func TestFrames(t *testing.T) {
144171
}
145172

146173
var expected = strings.Split(strings.TrimLeft(`
147-
Trace 0: goroutine 18 with at most 2 frames
148-
Func = testing.(*M).startAlarm.func1
149-
File = C:/Users/name/scoop/apps/go/current/src/testing/testing.go
150-
Line = 2241
151-
Func = time.goFunc
152-
File = C:/Users/name/scoop/apps/go/current/src/time/sleep.go
153-
Line = 176
174+
Trace 0: goroutine 7 with at most 2 frames
175+
Func = github.com/getsentry/sentry-go/internal/traceparser.TestGenerateTrace.func1
176+
File = c:/dev/sentry-go/internal/traceparser/parser_test.go
177+
Line = 23
178+
Func = github.com/getsentry/sentry-go/internal/traceparser.TestGenerateTrace
179+
File = c:/dev/sentry-go/internal/traceparser/parser_test.go
180+
Line = 17
154181
Trace 1: goroutine 1 with at most 6 frames
155182
Func = testing.(*T).Run
156183
File = C:/Users/name/scoop/apps/go/current/src/testing/testing.go
@@ -228,13 +255,13 @@ func TestFramesReversed(t *testing.T) {
228255
}
229256

230257
var expected = strings.Split(strings.TrimLeft(`
231-
Trace 0: goroutine 18 with at most 2 frames
232-
Func = time.goFunc
233-
File = C:/Users/name/scoop/apps/go/current/src/time/sleep.go
234-
Line = 176
235-
Func = testing.(*M).startAlarm.func1
236-
File = C:/Users/name/scoop/apps/go/current/src/testing/testing.go
237-
Line = 2241
258+
Trace 0: goroutine 7 with at most 2 frames
259+
Func = github.com/getsentry/sentry-go/internal/traceparser.TestGenerateTrace
260+
File = c:/dev/sentry-go/internal/traceparser/parser_test.go
261+
Line = 17
262+
Func = github.com/getsentry/sentry-go/internal/traceparser.TestGenerateTrace.func1
263+
File = c:/dev/sentry-go/internal/traceparser/parser_test.go
264+
Line = 23
238265
Trace 1: goroutine 1 with at most 6 frames
239266
Func = main.main
240267
File = _testmain.go

profiler_test.go

+1
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,7 @@ func validateProfile(t *testing.T, trace *profileTrace, duration time.Duration)
231231

232232
for _, frame := range trace.Frames {
233233
require.NotEmpty(frame.Function)
234+
require.NotContains(frame.Function, " ") // Space in the function name is likely a parsing error
234235
require.Greater(len(frame.AbsPath)+len(frame.Filename), 0)
235236
require.Greater(frame.Lineno, 0)
236237
}

0 commit comments

Comments
 (0)