Skip to content

Commit e06efb4

Browse files
adonovangopherbot
authored andcommitted
internal/gcimporter: bug.Report in export's panic handler
This CL effectively refines the telemetry report golang/go#71067 by pushing the bug.Report call down into the panic handler where the stack is still available. Fixes golang/go#71067 Change-Id: I354f01d3085f1547232bca499d0bd1f0bf2daef3 Reviewed-on: https://go-review.googlesource.com/c/tools/+/658355 LUCI-TryBot-Result: Go LUCI <[email protected]> Reviewed-by: Robert Findley <[email protected]> Auto-Submit: Alan Donovan <[email protected]>
1 parent 6c3e542 commit e06efb4

File tree

3 files changed

+20
-10
lines changed

3 files changed

+20
-10
lines changed

gopls/internal/cache/check.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -637,7 +637,10 @@ func (b *typeCheckBatch) checkPackageForImport(ctx context.Context, ph *packageH
637637
go func() {
638638
exportData, err := gcimporter.IExportShallow(b.fset, pkg, bug.Reportf)
639639
if err != nil {
640-
bug.Reportf("exporting package %v: %v", ph.mp.ID, err)
640+
// Internal error; the stack will have been reported via
641+
// bug.Reportf within IExportShallow, so there's not much
642+
// to do here (issue #71067).
643+
event.Error(ctx, "IExportShallow failed", err, label.Package.Of(string(ph.mp.ID)))
641644
return
642645
}
643646
if err := filecache.Set(exportDataKind, ph.key, exportData); err != nil {

internal/gcimporter/iexport.go

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -271,10 +271,10 @@ import (
271271
// file system, be sure to include a cryptographic digest of the executable in
272272
// the key to avoid version skew.
273273
//
274-
// If the provided reportf func is non-nil, it will be used for reporting bugs
275-
// encountered during export.
276-
// TODO(rfindley): remove reportf when we are confident enough in the new
277-
// objectpath encoding.
274+
// If the provided reportf func is non-nil, it is used for reporting
275+
// bugs (e.g. recovered panics) encountered during export, enabling us
276+
// to obtain via telemetry the stack that would otherwise be lost by
277+
// merely returning an error.
278278
func IExportShallow(fset *token.FileSet, pkg *types.Package, reportf ReportFunc) ([]byte, error) {
279279
// In principle this operation can only fail if out.Write fails,
280280
// but that's impossible for bytes.Buffer---and as a matter of
@@ -283,7 +283,7 @@ func IExportShallow(fset *token.FileSet, pkg *types.Package, reportf ReportFunc)
283283
// TODO(adonovan): use byte slices throughout, avoiding copying.
284284
const bundle, shallow = false, true
285285
var out bytes.Buffer
286-
err := iexportCommon(&out, fset, bundle, shallow, iexportVersion, []*types.Package{pkg})
286+
err := iexportCommon(&out, fset, bundle, shallow, iexportVersion, []*types.Package{pkg}, reportf)
287287
return out.Bytes(), err
288288
}
289289

@@ -323,20 +323,27 @@ const bundleVersion = 0
323323
// so that calls to IImportData can override with a provided package path.
324324
func IExportData(out io.Writer, fset *token.FileSet, pkg *types.Package) error {
325325
const bundle, shallow = false, false
326-
return iexportCommon(out, fset, bundle, shallow, iexportVersion, []*types.Package{pkg})
326+
return iexportCommon(out, fset, bundle, shallow, iexportVersion, []*types.Package{pkg}, nil)
327327
}
328328

329329
// IExportBundle writes an indexed export bundle for pkgs to out.
330330
func IExportBundle(out io.Writer, fset *token.FileSet, pkgs []*types.Package) error {
331331
const bundle, shallow = true, false
332-
return iexportCommon(out, fset, bundle, shallow, iexportVersion, pkgs)
332+
return iexportCommon(out, fset, bundle, shallow, iexportVersion, pkgs, nil)
333333
}
334334

335-
func iexportCommon(out io.Writer, fset *token.FileSet, bundle, shallow bool, version int, pkgs []*types.Package) (err error) {
335+
func iexportCommon(out io.Writer, fset *token.FileSet, bundle, shallow bool, version int, pkgs []*types.Package, reportf ReportFunc) (err error) {
336336
if !debug {
337337
defer func() {
338338
if e := recover(); e != nil {
339+
// Report the stack via telemetry (see #71067).
340+
if reportf != nil {
341+
reportf("panic in exporter")
342+
}
339343
if ierr, ok := e.(internalError); ok {
344+
// internalError usually means we exported a
345+
// bad go/types data structure: a violation
346+
// of an implicit precondition of Export.
340347
err = ierr
341348
return
342349
}

internal/gcimporter/iexport_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ import (
2929
func iexport(fset *token.FileSet, version int, pkg *types.Package) ([]byte, error) {
3030
var buf bytes.Buffer
3131
const bundle, shallow = false, false
32-
if err := gcimporter.IExportCommon(&buf, fset, bundle, shallow, version, []*types.Package{pkg}); err != nil {
32+
if err := gcimporter.IExportCommon(&buf, fset, bundle, shallow, version, []*types.Package{pkg}, nil); err != nil {
3333
return nil, err
3434
}
3535
return buf.Bytes(), nil

0 commit comments

Comments
 (0)