Skip to content

Commit f60a2a9

Browse files
prattmicgopherbot
authored andcommitted
cmd/compile: adjust inlined DW_AT_call_line by //line
insertInlCall mistakenly uses the absolute line number of the call rather than the relative line number (adjusted by //line). Switch to the correct line number. The call filename was already correct. Fixes golang#58648 Change-Id: Id8d1848895233e972d8cfe9c5789a88e62d06556 Reviewed-on: https://go-review.googlesource.com/c/go/+/470876 Reviewed-by: Than McIntosh <[email protected]> Run-TryBot: Michael Pratt <[email protected]> Auto-Submit: Michael Pratt <[email protected]> TryBot-Result: Gopher Robot <[email protected]> Reviewed-by: Cherry Mui <[email protected]>
1 parent 778a60c commit f60a2a9

File tree

2 files changed

+97
-75
lines changed

2 files changed

+97
-75
lines changed

src/cmd/compile/internal/dwarfgen/dwinl.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -273,13 +273,13 @@ func insertInlCall(dwcalls *dwarf.InlCalls, inlIdx int, imap map[int]int) int {
273273
// Create new entry for this inline
274274
inlinedFn := base.Ctxt.InlTree.InlinedFunction(inlIdx)
275275
callXPos := base.Ctxt.InlTree.CallPos(inlIdx)
276+
callPos := base.Ctxt.PosTable.Pos(callXPos)
277+
callFileSym := base.Ctxt.Lookup(callPos.Base().SymFilename())
276278
absFnSym := base.Ctxt.DwFixups.AbsFuncDwarfSym(inlinedFn)
277-
pb := base.Ctxt.PosTable.Pos(callXPos).Base()
278-
callFileSym := base.Ctxt.Lookup(pb.SymFilename())
279279
ic := dwarf.InlCall{
280280
InlIndex: inlIdx,
281281
CallFile: callFileSym,
282-
CallLine: uint32(callXPos.Line()),
282+
CallLine: uint32(callPos.RelLine()),
283283
AbsFunSym: absFnSym,
284284
Root: parCallIdx == -1,
285285
}

src/cmd/link/internal/ld/dwarf_test.go

Lines changed: 94 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -530,91 +530,113 @@ func inlined() int {
530530
return notinlined()
531531
}
532532
533+
%s
533534
func main() {
534535
x := inlined()
535536
G = x
536537
}
537538
`
538-
// Note: this is a build with "-l=4", as opposed to "-l -N". The
539-
// test is intended to verify DWARF that is only generated when
540-
// the inliner is active. We're only going to look at the DWARF for
541-
// main.main, however, hence we build with "-gcflags=-l=4" as opposed
542-
// to "-gcflags=all=-l=4".
543-
d, ex := gobuildAndExamine(t, prog, OptInl4)
539+
tests := []struct {
540+
name string
541+
prog string
542+
file string // basename
543+
line int64
544+
}{
545+
{
546+
name: "normal",
547+
prog: fmt.Sprintf(prog, ""),
548+
file: "test.go",
549+
line: 17,
550+
},
551+
{
552+
name: "line-directive",
553+
prog: fmt.Sprintf(prog, "//line /foobar.go:200"),
554+
file: "foobar.go",
555+
line: 201,
556+
},
557+
}
558+
for _, tc := range tests {
559+
tc := tc
560+
t.Run(tc.name, func(t *testing.T) {
561+
t.Parallel()
544562

545-
const (
546-
callFile = "test.go" // basename
547-
callLine = 16
548-
)
563+
// Note: this is a build with "-l=4", as opposed to "-l -N". The
564+
// test is intended to verify DWARF that is only generated when
565+
// the inliner is active. We're only going to look at the DWARF for
566+
// main.main, however, hence we build with "-gcflags=-l=4" as opposed
567+
// to "-gcflags=all=-l=4".
568+
d, ex := gobuildAndExamine(t, tc.prog, OptInl4)
549569

550-
maindie := findSubprogramDIE(t, ex, "main.main")
570+
maindie := findSubprogramDIE(t, ex, "main.main")
551571

552-
// Walk main's children and pick out the inlined subroutines
553-
mainIdx := ex.IdxFromOffset(maindie.Offset)
554-
childDies := ex.Children(mainIdx)
555-
found := false
556-
for _, child := range childDies {
557-
if child.Tag != dwarf.TagInlinedSubroutine {
558-
continue
559-
}
572+
// Walk main's children and pick out the inlined subroutines
573+
mainIdx := ex.IdxFromOffset(maindie.Offset)
574+
childDies := ex.Children(mainIdx)
575+
found := false
576+
for _, child := range childDies {
577+
if child.Tag != dwarf.TagInlinedSubroutine {
578+
continue
579+
}
560580

561-
// Found an inlined subroutine.
562-
if found {
563-
t.Fatalf("Found multiple inlined subroutines, expect only one")
564-
}
565-
found = true
581+
// Found an inlined subroutine.
582+
if found {
583+
t.Fatalf("Found multiple inlined subroutines, expect only one")
584+
}
585+
found = true
566586

567-
// Locate abstract origin.
568-
ooff, originOK := child.Val(dwarf.AttrAbstractOrigin).(dwarf.Offset)
569-
if !originOK {
570-
t.Fatalf("no abstract origin attr for inlined subroutine at offset %v", child.Offset)
571-
}
572-
originDIE := ex.EntryFromOffset(ooff)
573-
if originDIE == nil {
574-
t.Fatalf("can't locate origin DIE at off %v", ooff)
575-
}
587+
// Locate abstract origin.
588+
ooff, originOK := child.Val(dwarf.AttrAbstractOrigin).(dwarf.Offset)
589+
if !originOK {
590+
t.Fatalf("no abstract origin attr for inlined subroutine at offset %v", child.Offset)
591+
}
592+
originDIE := ex.EntryFromOffset(ooff)
593+
if originDIE == nil {
594+
t.Fatalf("can't locate origin DIE at off %v", ooff)
595+
}
576596

577-
// Name should check out.
578-
name, ok := originDIE.Val(dwarf.AttrName).(string)
579-
if !ok {
580-
t.Fatalf("no name attr for inlined subroutine at offset %v", child.Offset)
581-
}
582-
if name != "main.inlined" {
583-
t.Fatalf("expected inlined routine %s got %s", "main.cand", name)
584-
}
597+
// Name should check out.
598+
name, ok := originDIE.Val(dwarf.AttrName).(string)
599+
if !ok {
600+
t.Fatalf("no name attr for inlined subroutine at offset %v", child.Offset)
601+
}
602+
if name != "main.inlined" {
603+
t.Fatalf("expected inlined routine %s got %s", "main.cand", name)
604+
}
585605

586-
// Verify that the call_file attribute for the inlined
587-
// instance is ok. In this case it should match the file
588-
// for the main routine. To do this we need to locate the
589-
// compilation unit DIE that encloses what we're looking
590-
// at; this can be done with the examiner.
591-
cf, cfOK := child.Val(dwarf.AttrCallFile).(int64)
592-
if !cfOK {
593-
t.Fatalf("no call_file attr for inlined subroutine at offset %v", child.Offset)
594-
}
595-
file, err := ex.FileRef(d, mainIdx, cf)
596-
if err != nil {
597-
t.Errorf("FileRef: %v", err)
598-
continue
599-
}
600-
base := filepath.Base(file)
601-
if base != callFile {
602-
t.Errorf("bad call_file attribute, found '%s', want '%s'",
603-
file, callFile)
604-
}
606+
// Verify that the call_file attribute for the inlined
607+
// instance is ok. In this case it should match the file
608+
// for the main routine. To do this we need to locate the
609+
// compilation unit DIE that encloses what we're looking
610+
// at; this can be done with the examiner.
611+
cf, cfOK := child.Val(dwarf.AttrCallFile).(int64)
612+
if !cfOK {
613+
t.Fatalf("no call_file attr for inlined subroutine at offset %v", child.Offset)
614+
}
615+
file, err := ex.FileRef(d, mainIdx, cf)
616+
if err != nil {
617+
t.Errorf("FileRef: %v", err)
618+
continue
619+
}
620+
base := filepath.Base(file)
621+
if base != tc.file {
622+
t.Errorf("bad call_file attribute, found '%s', want '%s'",
623+
file, tc.file)
624+
}
605625

606-
// Verify that the call_line attribute for the inlined
607-
// instance is ok.
608-
cl, clOK := child.Val(dwarf.AttrCallLine).(int64)
609-
if !clOK {
610-
t.Fatalf("no call_line attr for inlined subroutine at offset %v", child.Offset)
611-
}
612-
if cl != callLine {
613-
t.Errorf("bad call_line attribute, found %d, want %d", cl, callLine)
614-
}
615-
}
616-
if !found {
617-
t.Fatalf("not enough inlined subroutines found in main.main")
626+
// Verify that the call_line attribute for the inlined
627+
// instance is ok.
628+
cl, clOK := child.Val(dwarf.AttrCallLine).(int64)
629+
if !clOK {
630+
t.Fatalf("no call_line attr for inlined subroutine at offset %v", child.Offset)
631+
}
632+
if cl != tc.line {
633+
t.Errorf("bad call_line attribute, found %d, want %d", cl, tc.line)
634+
}
635+
}
636+
if !found {
637+
t.Fatalf("not enough inlined subroutines found in main.main")
638+
}
639+
})
618640
}
619641
}
620642

0 commit comments

Comments
 (0)