proc: use cached packageVars in proc.(*EvalScope).PackageVariables

This commit is contained in:
aarzilli 2020-04-15 10:24:11 +02:00 committed by Derek Parker
parent cf37512aed
commit c078223d56
2 changed files with 35 additions and 27 deletions

@ -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("<unspecified>")
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

@ -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)