Fix crashes on Go dev.typeparams (soon to be Go main branch) (#2627)
* proc: Go 1.18 removes the _defer.siz field As of Go 1.17, the _defer.siz field is always 0 because _defer no longer stores defer call arguments at all. golang.org/cl/326062 removes it entirely for Go 1.18. Simply treat it as 0 if the field is missing from the _defer type. * proc: Go 1.18 changes _defer.fn from *funcval to func() golang.org/cl/325918 changed the type of the _defer.fn field from *funcval to func() for Go 1.18. This CL was later reverted because it caused failures in Delve, but we would like to un-revert it. Handle this change by inspecting the type of this field before decoding it.
This commit is contained in:
parent
cb73ef8f83
commit
a2b839990e
@ -5,6 +5,7 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"go/constant"
|
||||
"reflect"
|
||||
|
||||
"github.com/go-delve/delve/pkg/dwarf/frame"
|
||||
"github.com/go-delve/delve/pkg/dwarf/op"
|
||||
@ -519,11 +520,11 @@ func (it *stackIterator) loadG0SchedSP() {
|
||||
|
||||
// Defer represents one deferred call
|
||||
type Defer struct {
|
||||
DwrapPC uint64 // Value of field _defer.fn.fn, the deferred function or a wrapper to it in Go 1.17 or later
|
||||
DwrapPC uint64 // PC of the deferred function or, in Go 1.17+ a wrapper to it
|
||||
DeferPC uint64 // PC address of instruction that added this defer
|
||||
SP uint64 // Value of SP register when this function was deferred (this field gets adjusted when the stack is moved to match the new stack space)
|
||||
link *Defer // Next deferred function
|
||||
argSz int64
|
||||
argSz int64 // Always 0 in Go >=1.17
|
||||
|
||||
variable *Variable
|
||||
Unreadable error
|
||||
@ -580,8 +581,12 @@ func (d *Defer) load() {
|
||||
return
|
||||
}
|
||||
|
||||
fnvar := d.variable.fieldVariable("fn").maybeDereference()
|
||||
if fnvar.Addr != 0 {
|
||||
fnvar := d.variable.fieldVariable("fn")
|
||||
if fnvar.Kind == reflect.Func {
|
||||
// In Go 1.18, fn is a func().
|
||||
d.DwrapPC = fnvar.Base
|
||||
} else if val := fnvar.maybeDereference(); val.Addr != 0 {
|
||||
// In Go <1.18, fn is a *funcval.
|
||||
fnvar = fnvar.loadFieldNamed("fn")
|
||||
if fnvar.Unreadable == nil {
|
||||
d.DwrapPC, _ = constant.Uint64Val(fnvar.Value)
|
||||
@ -590,7 +595,14 @@ func (d *Defer) load() {
|
||||
|
||||
d.DeferPC, _ = constant.Uint64Val(d.variable.fieldVariable("pc").Value)
|
||||
d.SP, _ = constant.Uint64Val(d.variable.fieldVariable("sp").Value)
|
||||
d.argSz, _ = constant.Int64Val(d.variable.fieldVariable("siz").Value)
|
||||
sizVar := d.variable.fieldVariable("siz")
|
||||
if sizVar != nil {
|
||||
// In Go <1.18, siz stores the number of bytes of
|
||||
// defer arguments following the defer record. In Go
|
||||
// 1.18, the defer record doesn't store arguments, so
|
||||
// we leave this 0.
|
||||
d.argSz, _ = constant.Int64Val(sizVar.Value)
|
||||
}
|
||||
|
||||
linkvar := d.variable.fieldVariable("link").maybeDereference()
|
||||
if linkvar.Addr != 0 {
|
||||
|
Loading…
Reference in New Issue
Block a user