]> Cypherpunks repositories - gostls13.git/commitdiff
go/types, types2: dump position stack for non-bailout panics
authorMark Freeman <mark@golang.org>
Wed, 28 May 2025 15:10:53 +0000 (11:10 -0400)
committerGopher Robot <gobot@golang.org>
Wed, 28 May 2025 19:37:33 +0000 (12:37 -0700)
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>

src/cmd/compile/internal/types2/check.go
src/go/types/check.go

index d262ab9f851ffcdf98cce227950ce264f3abd225..31a1aa2abe9290b945c87d01693a7013d6c6caa3 100644 (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)
        }
index 77bff811b92ae72d14c690815cd525966dfff29d..e4e8e95c9974b9c3652606aa9821ab975a0af9de 100644 (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)
        }