go/types, types2: dump position stack for non-bailout panics

We make sure to dump to stderr since that's where the panic information
ends up. Long traces get truncated with a "..." in the middle. We pick
an arbitrary limit of 10 positions, but this could be changed.

For #51603

Change-Id: I02326a93181e94e1c48afc05684240540c2c90ba
Reviewed-on: https://go-review.googlesource.com/c/go/+/676815
Reviewed-by: Robert Griesemer <gri@google.com>
Auto-Submit: Mark Freeman <mark@golang.org>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
This commit is contained in:
Mark Freeman 2025-05-28 11:10:53 -04:00 committed by Gopher Robot
parent 70109eb326
commit 18ad74dd36
2 changed files with 38 additions and 2 deletions

View file

@ -11,6 +11,7 @@ import (
"fmt"
"go/constant"
. "internal/types/errors"
"os"
"sync/atomic"
)
@ -419,7 +420,24 @@ func (check *Checker) handleBailout(err *error) {
// normal return or early exit
*err = check.firstErr
default:
// TODO(markfreeman): dump posStack if available
if len(check.posStack) > 0 {
doPrint := func(ps []syntax.Pos) {
for i := len(ps) - 1; i >= 0; i-- {
fmt.Fprintf(os.Stderr, "\t%v\n", ps[i])
}
}
fmt.Fprintln(os.Stderr, "The following panic happened checking types near:")
if len(check.posStack) <= 10 {
doPrint(check.posStack)
} else {
// if it's long, truncate the middle; it's least likely to help
doPrint(check.posStack[len(check.posStack)-5:])
fmt.Fprintln(os.Stderr, "\t...")
doPrint(check.posStack[:5])
}
}
// re-panic
panic(p)
}

View file

@ -13,6 +13,7 @@ import (
"go/token"
"internal/godebug"
. "internal/types/errors"
"os"
"sync/atomic"
)
@ -444,7 +445,24 @@ func (check *Checker) handleBailout(err *error) {
// normal return or early exit
*err = check.firstErr
default:
// TODO(markfreeman): dump posStack if available
if len(check.posStack) > 0 {
doPrint := func(ps []positioner) {
for i := len(ps) - 1; i >= 0; i-- {
fmt.Fprintf(os.Stderr, "\t%v\n", check.fset.Position(ps[i].Pos()))
}
}
fmt.Fprintln(os.Stderr, "The following panic happened checking types near:")
if len(check.posStack) <= 10 {
doPrint(check.posStack)
} else {
// if it's long, truncate the middle; it's least likely to help
doPrint(check.posStack[len(check.posStack)-5:])
fmt.Fprintln(os.Stderr, "\t...")
doPrint(check.posStack[:5])
}
}
// re-panic
panic(p)
}