diff --git a/pkg/proc/eval.go b/pkg/proc/eval.go index ce85f597..d541bb87 100644 --- a/pkg/proc/eval.go +++ b/pkg/proc/eval.go @@ -451,36 +451,33 @@ func regsReplaceStaticBase(regs op.DwarfRegisters, image *Image) op.DwarfRegiste // PackageVariables returns the name, value, and type of all package variables in the application. func (scope *EvalScope) PackageVariables(cfg LoadConfig) ([]*Variable, error) { - var vars []*Variable - for _, image := range scope.BinInfo.Images { - if image.loadErr != nil { + pkgvars := make([]packageVar, len(scope.BinInfo.packageVars)) + copy(pkgvars, scope.BinInfo.packageVars) + sort.Slice(pkgvars, func(i, j int) bool { + if pkgvars[i].cu.image.addr == pkgvars[j].cu.image.addr { + return pkgvars[i].offset < pkgvars[j].offset + } + return pkgvars[i].cu.image.addr < pkgvars[j].cu.image.addr + }) + vars := make([]*Variable, 0, len(scope.BinInfo.packageVars)) + for _, pkgvar := range pkgvars { + reader := pkgvar.cu.image.dwarfReader + reader.Seek(pkgvar.offset) + entry, err := reader.Next() + if err != nil { + return nil, err + } + + // Ignore errors trying to extract values + val, err := extractVarInfoFromEntry(scope.BinInfo, pkgvar.cu.image, regsReplaceStaticBase(scope.Regs, pkgvar.cu.image), scope.Mem, godwarf.EntryToTree(entry)) + if val.Kind == reflect.Invalid { continue } - reader := reader.New(image.dwarf) - - var utypoff dwarf.Offset - utypentry, err := reader.SeekToTypeNamed("") - if err == nil { - utypoff = utypentry.Offset - } - - for entry, err := reader.NextPackageVariable(); entry != nil; entry, err = reader.NextPackageVariable() { - if err != nil { - return nil, err - } - - if typoff, ok := entry.Val(dwarf.AttrType).(dwarf.Offset); !ok || typoff == utypoff { - continue - } - - // Ignore errors trying to extract values - val, err := extractVarInfoFromEntry(scope.BinInfo, image, regsReplaceStaticBase(scope.Regs, image), scope.Mem, godwarf.EntryToTree(entry)) - if err != nil { - continue - } - val.loadValue(cfg) - vars = append(vars, val) + if err != nil { + continue } + val.loadValue(cfg) + vars = append(vars, val) } return vars, nil diff --git a/pkg/proc/proc_test.go b/pkg/proc/proc_test.go index ce29f5a7..d0b7ad44 100644 --- a/pkg/proc/proc_test.go +++ b/pkg/proc/proc_test.go @@ -1827,6 +1827,14 @@ func TestIssue414(t *testing.T) { } func TestPackageVariables(t *testing.T) { + var skippedVariable = map[string]bool{ + "runtime.uint16Eface": true, + "runtime.uint32Eface": true, + "runtime.uint64Eface": true, + "runtime.stringEface": true, + "runtime.sliceEface": true, + } + protest.AllowRecording(t) withTestProcess("testvariables", t, func(p *proc.Target, fixture protest.Fixture) { err := p.Continue() @@ -1837,6 +1845,9 @@ func TestPackageVariables(t *testing.T) { assertNoError(err, t, "PackageVariables()") failed := false for _, v := range vars { + if skippedVariable[v.Name] { + continue + } if v.Unreadable != nil && v.Unreadable.Error() != "no location attribute Location" { failed = true t.Logf("Unreadable variable %s: %v", v.Name, v.Unreadable)