Skip to content

Commit

Permalink
proc: fix findCompileUnitForOffset when plugins are used
Browse files Browse the repository at this point in the history
Splits the compileUnits slice between images so that we can search for
an offset inside the debug info of a specific image file.
  • Loading branch information
aarzilli authored and derekparker committed May 1, 2020
1 parent 96890bb commit 8f5df19
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 25 deletions.
55 changes: 31 additions & 24 deletions pkg/proc/bininfo.go
Expand Up @@ -84,8 +84,6 @@ type BinaryInfo struct {

frameEntries frame.FrameDescriptionEntries

compileUnits []*compileUnit // compileUnits is sorted by increasing DWARF offset

types map[string]dwarfRef
packageVars []packageVar // packageVars is a list of all global/package variables in debug_info, sorted by address

Expand Down Expand Up @@ -520,14 +518,17 @@ func (err *ErrCouldNotFindLine) Error() string {
func (bi *BinaryInfo) LineToPC(filename string, lineno int) (pcs []uint64, err error) {
fileFound := false
var pc uint64
for _, cu := range bi.compileUnits {
if cu.lineInfo == nil || cu.lineInfo.Lookup[filename] == nil {
continue
}
fileFound = true
pc = cu.lineInfo.LineToPC(filename, lineno)
if pc != 0 {
break
pcsearch:
for _, image := range bi.Images {
for _, cu := range image.compileUnits {
if cu.lineInfo == nil || cu.lineInfo.Lookup[filename] == nil {
continue
}
fileFound = true
pc = cu.lineInfo.LineToPC(filename, lineno)
if pc != 0 {
break pcsearch
}
}
}

Expand Down Expand Up @@ -580,9 +581,11 @@ func (bi *BinaryInfo) AllPCsForFileLines(filename string, linenos []int) map[int
for _, line := range linenos {
r[line] = make([]uint64, 0, 1)
}
for _, cu := range bi.compileUnits {
if cu.lineInfo != nil && cu.lineInfo.Lookup[filename] != nil {
cu.lineInfo.AllPCsForFileLines(filename, r)
for _, image := range bi.Images {
for _, cu := range image.compileUnits {
if cu.lineInfo != nil && cu.lineInfo.Lookup[filename] != nil {
cu.lineInfo.AllPCsForFileLines(filename, r)
}
}
}
return r
Expand Down Expand Up @@ -648,6 +651,8 @@ type Image struct {

typeCache map[dwarf.Offset]godwarf.Type

compileUnits []*compileUnit // compileUnits is sorted by increasing DWARF offset

dwarfTreeCache *simplelru.LRU

// runtimeTypeToDIE maps between the offset of a runtime._type in
Expand Down Expand Up @@ -871,7 +876,7 @@ func (bi *BinaryInfo) LocationCovers(entry *dwarf.Entry, attr dwarf.Attr) ([][2]
if !ok {
return nil, fmt.Errorf("attribute %s of unsupported type %T", attr, a)
}
cu := bi.findCompileUnitForOffset(entry.Offset)
cu := bi.Images[0].findCompileUnitForOffset(entry.Offset)
if cu == nil {
return nil, errors.New("could not find compile unit")
}
Expand Down Expand Up @@ -938,17 +943,19 @@ func (bi *BinaryInfo) loclistEntry(off int64, pc uint64) []byte {

// findCompileUnit returns the compile unit containing address pc.
func (bi *BinaryInfo) findCompileUnit(pc uint64) *compileUnit {
for _, cu := range bi.compileUnits {
for _, rng := range cu.ranges {
if pc >= rng[0] && pc < rng[1] {
return cu
for _, image := range bi.Images {
for _, cu := range image.compileUnits {
for _, rng := range cu.ranges {
if pc >= rng[0] && pc < rng[1] {
return cu
}
}
}
}
return nil
}

func (bi *BinaryInfo) findCompileUnitForOffset(off dwarf.Offset) *compileUnit {
func (bi *Image) findCompileUnitForOffset(off dwarf.Offset) *compileUnit {
i := sort.Search(len(bi.compileUnits), func(i int) bool {
return bi.compileUnits[i].offset >= off
})
Expand All @@ -960,7 +967,7 @@ func (bi *BinaryInfo) findCompileUnitForOffset(off dwarf.Offset) *compileUnit {

// Producer returns the value of DW_AT_producer.
func (bi *BinaryInfo) Producer() string {
for _, cu := range bi.compileUnits {
for _, cu := range bi.Images[0].compileUnits {
if cu.isgo && cu.producer != "" {
return cu.producer
}
Expand Down Expand Up @@ -1569,7 +1576,7 @@ func (bi *BinaryInfo) loadDebugInfoMaps(image *Image, debugLineBytes []byte, wg
if cu.isgo && gopkg != "" {
bi.PackageMap[gopkg] = append(bi.PackageMap[gopkg], escapePackagePath(strings.Replace(cu.name, "\\", "/", -1)))
}
bi.compileUnits = append(bi.compileUnits, cu)
image.compileUnits = append(image.compileUnits, cu)
if entry.Children {
bi.loadDebugInfoMapsCompileUnit(ctxt, image, reader, cu)
}
Expand All @@ -1583,7 +1590,7 @@ func (bi *BinaryInfo) loadDebugInfoMaps(image *Image, debugLineBytes []byte, wg
}
}

sort.Sort(compileUnitsByOffset(bi.compileUnits))
sort.Sort(compileUnitsByOffset(image.compileUnits))
sort.Sort(functionsDebugInfoByEntry(bi.Functions))
sort.Sort(packageVarsByAddr(bi.packageVars))

Expand All @@ -1593,7 +1600,7 @@ func (bi *BinaryInfo) loadDebugInfoMaps(image *Image, debugLineBytes []byte, wg
}

bi.Sources = []string{}
for _, cu := range bi.compileUnits {
for _, cu := range image.compileUnits {
if cu.lineInfo != nil {
for _, fileEntry := range cu.lineInfo.FileNames {
bi.Sources = append(bi.Sources, fileEntry.Path)
Expand Down Expand Up @@ -1997,7 +2004,7 @@ type PackageBuildInfo struct {
// files constituting the package.
func (bi *BinaryInfo) ListPackagesBuildInfo(includeFiles bool) []*PackageBuildInfo {
m := make(map[string]*PackageBuildInfo)
for _, cu := range bi.compileUnits {
for _, cu := range bi.Images[0].compileUnits {
if cu.image != bi.Images[0] || !cu.isgo || cu.lineInfo == nil {
//TODO(aarzilli): what's the correct thing to do for plugins?
continue
Expand Down
2 changes: 1 addition & 1 deletion pkg/proc/variables.go
Expand Up @@ -588,7 +588,7 @@ func newVariable(name string, addr uintptr, dwarfType godwarf.Type, bi *BinaryIn
// b. anonymous struct types (they contain the '{' character)
// c. Go internal struct types used to describe maps (they contain the '<'
// character).
cu := bi.findCompileUnitForOffset(dwarfType.Common().Offset)
cu := bi.Images[dwarfType.Common().Index].findCompileUnitForOffset(dwarfType.Common().Offset)
if cu != nil && cu.isgo {
dwarfType = &godwarf.TypedefType{
CommonType: *(dwarfType.Common()),
Expand Down

0 comments on commit 8f5df19

Please sign in to comment.