proc: make moduleDataToImage more robust (#2613)
Conversion form a moduledata object into an image object was implemented by looking for a function covering the start address of the text section of the moduledata object, and then converting that into its corresponding image. Unfortunately this seems to not always work. In particular it does not work on linux/386 with go1.17 (but it might also fail on other combinations): the start address of the text section is, for whatever reason, not part of any function. As a fallback simply scan all images we know of and return the closest one that has start address less than or equal to the start address of the text section we are looking for. Fixes TestPluginVariables on go1.17/linux/386. Fixes #2611 Co-authored-by: a <a@kra>
This commit is contained in:
parent
f74b7a6e39
commit
39274f6028
@ -715,14 +715,28 @@ func (bi *BinaryInfo) AddImage(path string, addr uint64) error {
|
|||||||
|
|
||||||
// moduleDataToImage finds the image corresponding to the given module data object.
|
// moduleDataToImage finds the image corresponding to the given module data object.
|
||||||
func (bi *BinaryInfo) moduleDataToImage(md *moduleData) *Image {
|
func (bi *BinaryInfo) moduleDataToImage(md *moduleData) *Image {
|
||||||
return bi.funcToImage(bi.PCToFunc(uint64(md.text)))
|
fn := bi.PCToFunc(uint64(md.text))
|
||||||
|
if fn != nil {
|
||||||
|
return bi.funcToImage(fn)
|
||||||
|
}
|
||||||
|
// Try searching for the image with the closest address preceding md.text
|
||||||
|
var so *Image
|
||||||
|
for i := range bi.Images {
|
||||||
|
if bi.Images[i].StaticBase > md.text {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if so == nil || bi.Images[i].StaticBase > so.StaticBase {
|
||||||
|
so = bi.Images[i]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return so
|
||||||
}
|
}
|
||||||
|
|
||||||
// imageToModuleData finds the module data in mds corresponding to the given image.
|
// imageToModuleData finds the module data in mds corresponding to the given image.
|
||||||
func (bi *BinaryInfo) imageToModuleData(image *Image, mds []moduleData) *moduleData {
|
func (bi *BinaryInfo) imageToModuleData(image *Image, mds []moduleData) *moduleData {
|
||||||
for _, md := range mds {
|
for _, md := range mds {
|
||||||
im2 := bi.moduleDataToImage(&md)
|
im2 := bi.moduleDataToImage(&md)
|
||||||
if im2.index == image.index {
|
if im2 != nil && im2.index == image.index {
|
||||||
return &md
|
return &md
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -134,17 +134,19 @@ func runtimeTypeToDIE(_type *Variable, dataAddr uint64) (typ godwarf.Type, kind
|
|||||||
md := findModuleDataForType(bi, mds, _type.Addr, _type.mem)
|
md := findModuleDataForType(bi, mds, _type.Addr, _type.mem)
|
||||||
if md != nil {
|
if md != nil {
|
||||||
so := bi.moduleDataToImage(md)
|
so := bi.moduleDataToImage(md)
|
||||||
if rtdie, ok := so.runtimeTypeToDIE[uint64(_type.Addr-md.types)]; ok {
|
if so != nil {
|
||||||
typ, err := godwarf.ReadType(so.dwarf, so.index, rtdie.offset, so.typeCache)
|
if rtdie, ok := so.runtimeTypeToDIE[uint64(_type.Addr-md.types)]; ok {
|
||||||
if err != nil {
|
typ, err := godwarf.ReadType(so.dwarf, so.index, rtdie.offset, so.typeCache)
|
||||||
return nil, 0, fmt.Errorf("invalid interface type: %v", err)
|
if err != nil {
|
||||||
}
|
return nil, 0, fmt.Errorf("invalid interface type: %v", err)
|
||||||
if rtdie.kind == -1 {
|
|
||||||
if kindField := _type.loadFieldNamed("kind"); kindField != nil && kindField.Value != nil {
|
|
||||||
rtdie.kind, _ = constant.Int64Val(kindField.Value)
|
|
||||||
}
|
}
|
||||||
|
if rtdie.kind == -1 {
|
||||||
|
if kindField := _type.loadFieldNamed("kind"); kindField != nil && kindField.Value != nil {
|
||||||
|
rtdie.kind, _ = constant.Int64Val(kindField.Value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return typ, rtdie.kind, nil
|
||||||
}
|
}
|
||||||
return typ, rtdie.kind, nil
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user