Skip to content

Commit

Permalink
stack: add support for 1.17 stack traces (#74)
Browse files Browse the repository at this point in the history
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
  • Loading branch information
MordFustang21 committed Mar 17, 2022
1 parent 19b8520 commit 426572b
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 9 deletions.
24 changes: 15 additions & 9 deletions stack/context.go
Expand Up @@ -257,14 +257,15 @@ var (
// gotRaceHeader1, done
raceHeaderFooter = []byte("==================")
// gotRaceHeader2
raceHeader = []byte("WARNING: DATA RACE")
crlf = []byte("\r\n")
lf = []byte("\n")
commaSpace = []byte(", ")
writeCap = []byte("Write")
writeLow = []byte("write")
threeDots = []byte("...")
underscore = []byte("_")
raceHeader = []byte("WARNING: DATA RACE")
crlf = []byte("\r\n")
lf = []byte("\n")
commaSpace = []byte(", ")
writeCap = []byte("Write")
writeLow = []byte("write")
threeDots = []byte("...")
underscore = []byte("_")
inaccurateQuestionMark = []byte("?")
)

// These are effectively constants.
Expand Down Expand Up @@ -854,13 +855,18 @@ func parseArgs(line []byte) (Args, error) {
arg := Arg{IsOffsetTooLarge: true}
cur.Values = append(cur.Values, arg)
default:
inaccurate := bytes.HasSuffix(a, inaccurateQuestionMark)
if inaccurate {
a = a[:len(a)-len(inaccurateQuestionMark)]
}

v, err := strconv.ParseUint(unsafeString(a), 0, 64)
if err != nil {
return Args{}, errors.New("failed to parse int")
}
// Assume the stack was generated with the same bitness (32 vs 64) as
// the code processing it.
arg := Arg{Value: v, IsPtr: v > pointerFloor && v < pointerCeiling}
arg := Arg{Value: v, IsPtr: v > pointerFloor && v < pointerCeiling, IsInaccurate: inaccurate}
cur.Values = append(cur.Values, arg)
}
}
Expand Down
50 changes: 50 additions & 0 deletions stack/context_test.go
Expand Up @@ -1057,6 +1057,56 @@ func TestScanSnapshotSynthetic(t *testing.T) {
},
},

{
name: "WithCarriageReturn1.18Inaccurate",
in: []string{
"goroutine 1 [running]:",
"github.com/cockroachdb/cockroach/storage/engine._Cfunc_DBIterSeek()",
" ??:0 +0x6d",
"gopkg.in/yaml%2ev2.handleErr(0x433b20?)",
"\t/gopath/src/gopkg.in/yaml.v2/yaml.go:153 +0xc6",
"reflect.Value.assignTo(0x570860, 0x803f3e0, 0x15)",
"\t/goroot/src/reflect/value.go:2125 +0x368",
"main.main()",
"\t/gopath/src/github.com/maruel/panicparse/stack/stack.go:428 +0x27",
"",
},
err: io.EOF,
want: []*Goroutine{
{
Signature: Signature{
State: "running",
Stack: Stack{
Calls: []Call{
newCall(
"github.com/cockroachdb/cockroach/storage/engine._Cfunc_DBIterSeek",
Args{},
"??",
0),
newCall(
"gopkg.in/yaml%2ev2.handleErr",
Args{Values: []Arg{{Value: 0x433b20, IsPtr: true, IsInaccurate: true}}},
"/gopath/src/gopkg.in/yaml.v2/yaml.go",
153),
newCall(
"reflect.Value.assignTo",
Args{Values: []Arg{{Value: 0x570860, IsPtr: true}, {Value: 0x803f3e0, IsPtr: true}, {Value: 0x15}}},
"/goroot/src/reflect/value.go",
2125),
newCall(
"main.main",
Args{},
"/gopath/src/github.com/maruel/panicparse/stack/stack.go",
428),
},
},
},
ID: 1,
First: true,
},
},
},

// goconvey is culprit of this.
{
name: "Indented",
Expand Down
4 changes: 4 additions & 0 deletions stack/stack.go
Expand Up @@ -122,6 +122,10 @@ type Arg struct {
// preventing the argument from being printed in the stack trace.
IsOffsetTooLarge bool

// IsInaccurate determines if Value is inaccurate. Stacks could have inaccurate values
// for arguments passed in registers. Go 1.18 prints a ? for these values.
IsInaccurate bool

// The following are set if IsAggregate == true.

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

0 comments on commit 426572b

Please sign in to comment.