Skip to content

Commit 426572b

Browse files
stack: add support for 1.17 stack traces (#74)
go1.17 adds "uncertainty" to the stack trace. Add support to process the trailing "?" and add Arg.IsInaccurate to represent this. https://go.dev/doc/go1.17#compiler
1 parent 19b8520 commit 426572b

3 files changed

Lines changed: 69 additions & 9 deletions

File tree

stack/context.go

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -257,14 +257,15 @@ var (
257257
// gotRaceHeader1, done
258258
raceHeaderFooter = []byte("==================")
259259
// gotRaceHeader2
260-
raceHeader = []byte("WARNING: DATA RACE")
261-
crlf = []byte("\r\n")
262-
lf = []byte("\n")
263-
commaSpace = []byte(", ")
264-
writeCap = []byte("Write")
265-
writeLow = []byte("write")
266-
threeDots = []byte("...")
267-
underscore = []byte("_")
260+
raceHeader = []byte("WARNING: DATA RACE")
261+
crlf = []byte("\r\n")
262+
lf = []byte("\n")
263+
commaSpace = []byte(", ")
264+
writeCap = []byte("Write")
265+
writeLow = []byte("write")
266+
threeDots = []byte("...")
267+
underscore = []byte("_")
268+
inaccurateQuestionMark = []byte("?")
268269
)
269270

270271
// These are effectively constants.
@@ -854,13 +855,18 @@ func parseArgs(line []byte) (Args, error) {
854855
arg := Arg{IsOffsetTooLarge: true}
855856
cur.Values = append(cur.Values, arg)
856857
default:
858+
inaccurate := bytes.HasSuffix(a, inaccurateQuestionMark)
859+
if inaccurate {
860+
a = a[:len(a)-len(inaccurateQuestionMark)]
861+
}
862+
857863
v, err := strconv.ParseUint(unsafeString(a), 0, 64)
858864
if err != nil {
859865
return Args{}, errors.New("failed to parse int")
860866
}
861867
// Assume the stack was generated with the same bitness (32 vs 64) as
862868
// the code processing it.
863-
arg := Arg{Value: v, IsPtr: v > pointerFloor && v < pointerCeiling}
869+
arg := Arg{Value: v, IsPtr: v > pointerFloor && v < pointerCeiling, IsInaccurate: inaccurate}
864870
cur.Values = append(cur.Values, arg)
865871
}
866872
}

stack/context_test.go

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1057,6 +1057,56 @@ func TestScanSnapshotSynthetic(t *testing.T) {
10571057
},
10581058
},
10591059

1060+
{
1061+
name: "WithCarriageReturn1.18Inaccurate",
1062+
in: []string{
1063+
"goroutine 1 [running]:",
1064+
"github.com/cockroachdb/cockroach/storage/engine._Cfunc_DBIterSeek()",
1065+
" ??:0 +0x6d",
1066+
"gopkg.in/yaml%2ev2.handleErr(0x433b20?)",
1067+
"\t/gopath/src/gopkg.in/yaml.v2/yaml.go:153 +0xc6",
1068+
"reflect.Value.assignTo(0x570860, 0x803f3e0, 0x15)",
1069+
"\t/goroot/src/reflect/value.go:2125 +0x368",
1070+
"main.main()",
1071+
"\t/gopath/src/github.com/maruel/panicparse/stack/stack.go:428 +0x27",
1072+
"",
1073+
},
1074+
err: io.EOF,
1075+
want: []*Goroutine{
1076+
{
1077+
Signature: Signature{
1078+
State: "running",
1079+
Stack: Stack{
1080+
Calls: []Call{
1081+
newCall(
1082+
"github.com/cockroachdb/cockroach/storage/engine._Cfunc_DBIterSeek",
1083+
Args{},
1084+
"??",
1085+
0),
1086+
newCall(
1087+
"gopkg.in/yaml%2ev2.handleErr",
1088+
Args{Values: []Arg{{Value: 0x433b20, IsPtr: true, IsInaccurate: true}}},
1089+
"/gopath/src/gopkg.in/yaml.v2/yaml.go",
1090+
153),
1091+
newCall(
1092+
"reflect.Value.assignTo",
1093+
Args{Values: []Arg{{Value: 0x570860, IsPtr: true}, {Value: 0x803f3e0, IsPtr: true}, {Value: 0x15}}},
1094+
"/goroot/src/reflect/value.go",
1095+
2125),
1096+
newCall(
1097+
"main.main",
1098+
Args{},
1099+
"/gopath/src/github.com/maruel/panicparse/stack/stack.go",
1100+
428),
1101+
},
1102+
},
1103+
},
1104+
ID: 1,
1105+
First: true,
1106+
},
1107+
},
1108+
},
1109+
10601110
// goconvey is culprit of this.
10611111
{
10621112
name: "Indented",

stack/stack.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,10 @@ type Arg struct {
122122
// preventing the argument from being printed in the stack trace.
123123
IsOffsetTooLarge bool
124124

125+
// IsInaccurate determines if Value is inaccurate. Stacks could have inaccurate values
126+
// for arguments passed in registers. Go 1.18 prints a ? for these values.
127+
IsInaccurate bool
128+
125129
// The following are set if IsAggregate == true.
126130

127131
// Fields are the fields/elements of aggregate-typed arguments.

0 commit comments

Comments
 (0)