diff --git a/pkg/dwarf/dwarfbuilder/info.go b/pkg/dwarf/dwarfbuilder/info.go index 3288046715..7d264b01cd 100644 --- a/pkg/dwarf/dwarfbuilder/info.go +++ b/pkg/dwarf/dwarfbuilder/info.go @@ -92,7 +92,9 @@ func (b *Builder) TagOpen(tag dwarf.Tag, name string) dwarf.Offset { ts.tag = tag b.info.WriteByte(0) b.tagStack = append(b.tagStack, ts) - b.Attr(dwarf.AttrName, name) + if name != "" { + b.Attr(dwarf.AttrName, name) + } return ts.off } diff --git a/pkg/proc/dwarf_expr_test.go b/pkg/proc/dwarf_expr_test.go index 34aeb7c161..fe4ecc9e51 100644 --- a/pkg/proc/dwarf_expr_test.go +++ b/pkg/proc/dwarf_expr_test.go @@ -292,3 +292,18 @@ func TestLocationCovers(t *testing.T) { } } + +func TestIssue1636_InlineWithoutOrigin(t *testing.T) { + // Gcc (specifically GNU C++11 6.3.0) will emit DW_TAG_inlined_subroutine + // without a DW_AT_abstract_origin or a name. What is an inlined subroutine + // without a reference to an abstract origin or even a name? Regardless, + // Delve shouldn't crash. + dwb := dwarfbuilder.New() + dwb.AddCompileUnit("main", 0x0) + dwb.AddSubprogram("main.main", 0x40100, 0x41000) + dwb.TagOpen(dwarf.TagInlinedSubroutine, "") + dwb.TagClose() + dwb.TagClose() + dwb.TagClose() + fakeBinaryInfo(t, dwb) +} diff --git a/pkg/proc/types.go b/pkg/proc/types.go index b560d29e04..6cf29568c9 100644 --- a/pkg/proc/types.go +++ b/pkg/proc/types.go @@ -410,7 +410,7 @@ func (bi *BinaryInfo) loadDebugInfoMapsCompileUnit(ctxt *loadDebugInfoMapsContex if entry.Tag == 0 { break } - if entry.Tag == dwarf.TagInlinedSubroutine { + if entry.Tag == dwarf.TagInlinedSubroutine && entry.Val(dwarf.AttrAbstractOrigin) != nil { originOffset := entry.Val(dwarf.AttrAbstractOrigin).(dwarf.Offset) name := ctxt.abstractOriginNameTable[originOffset] if ranges, _ := image.dwarf.Ranges(entry); len(ranges) == 1 {