mirror of
https://github.com/golang/go
synced 2024-11-23 23:40:13 -07:00
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 #58648 Change-Id: Id8d1848895233e972d8cfe9c5789a88e62d06556 Reviewed-on: https://go-review.googlesource.com/c/go/+/470876 Reviewed-by: Than McIntosh <thanm@google.com> Run-TryBot: Michael Pratt <mpratt@google.com> Auto-Submit: Michael Pratt <mpratt@google.com> TryBot-Result: Gopher Robot <gobot@golang.org> Reviewed-by: Cherry Mui <cherryyz@google.com>
This commit is contained in:
parent
778a60c103
commit
f60a2a9c94
@ -273,13 +273,13 @@ func insertInlCall(dwcalls *dwarf.InlCalls, inlIdx int, imap map[int]int) int {
|
|||||||
// Create new entry for this inline
|
// Create new entry for this inline
|
||||||
inlinedFn := base.Ctxt.InlTree.InlinedFunction(inlIdx)
|
inlinedFn := base.Ctxt.InlTree.InlinedFunction(inlIdx)
|
||||||
callXPos := base.Ctxt.InlTree.CallPos(inlIdx)
|
callXPos := base.Ctxt.InlTree.CallPos(inlIdx)
|
||||||
|
callPos := base.Ctxt.PosTable.Pos(callXPos)
|
||||||
|
callFileSym := base.Ctxt.Lookup(callPos.Base().SymFilename())
|
||||||
absFnSym := base.Ctxt.DwFixups.AbsFuncDwarfSym(inlinedFn)
|
absFnSym := base.Ctxt.DwFixups.AbsFuncDwarfSym(inlinedFn)
|
||||||
pb := base.Ctxt.PosTable.Pos(callXPos).Base()
|
|
||||||
callFileSym := base.Ctxt.Lookup(pb.SymFilename())
|
|
||||||
ic := dwarf.InlCall{
|
ic := dwarf.InlCall{
|
||||||
InlIndex: inlIdx,
|
InlIndex: inlIdx,
|
||||||
CallFile: callFileSym,
|
CallFile: callFileSym,
|
||||||
CallLine: uint32(callXPos.Line()),
|
CallLine: uint32(callPos.RelLine()),
|
||||||
AbsFunSym: absFnSym,
|
AbsFunSym: absFnSym,
|
||||||
Root: parCallIdx == -1,
|
Root: parCallIdx == -1,
|
||||||
}
|
}
|
||||||
|
@ -530,91 +530,113 @@ func inlined() int {
|
|||||||
return notinlined()
|
return notinlined()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
%s
|
||||||
func main() {
|
func main() {
|
||||||
x := inlined()
|
x := inlined()
|
||||||
G = x
|
G = x
|
||||||
}
|
}
|
||||||
`
|
`
|
||||||
// Note: this is a build with "-l=4", as opposed to "-l -N". The
|
tests := []struct {
|
||||||
// test is intended to verify DWARF that is only generated when
|
name string
|
||||||
// the inliner is active. We're only going to look at the DWARF for
|
prog string
|
||||||
// main.main, however, hence we build with "-gcflags=-l=4" as opposed
|
file string // basename
|
||||||
// to "-gcflags=all=-l=4".
|
line int64
|
||||||
d, ex := gobuildAndExamine(t, prog, OptInl4)
|
}{
|
||||||
|
{
|
||||||
const (
|
name: "normal",
|
||||||
callFile = "test.go" // basename
|
prog: fmt.Sprintf(prog, ""),
|
||||||
callLine = 16
|
file: "test.go",
|
||||||
)
|
line: 17,
|
||||||
|
},
|
||||||
maindie := findSubprogramDIE(t, ex, "main.main")
|
{
|
||||||
|
name: "line-directive",
|
||||||
// Walk main's children and pick out the inlined subroutines
|
prog: fmt.Sprintf(prog, "//line /foobar.go:200"),
|
||||||
mainIdx := ex.IdxFromOffset(maindie.Offset)
|
file: "foobar.go",
|
||||||
childDies := ex.Children(mainIdx)
|
line: 201,
|
||||||
found := false
|
},
|
||||||
for _, child := range childDies {
|
|
||||||
if child.Tag != dwarf.TagInlinedSubroutine {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
// Found an inlined subroutine.
|
|
||||||
if found {
|
|
||||||
t.Fatalf("Found multiple inlined subroutines, expect only one")
|
|
||||||
}
|
|
||||||
found = true
|
|
||||||
|
|
||||||
// Locate abstract origin.
|
|
||||||
ooff, originOK := child.Val(dwarf.AttrAbstractOrigin).(dwarf.Offset)
|
|
||||||
if !originOK {
|
|
||||||
t.Fatalf("no abstract origin attr for inlined subroutine at offset %v", child.Offset)
|
|
||||||
}
|
|
||||||
originDIE := ex.EntryFromOffset(ooff)
|
|
||||||
if originDIE == nil {
|
|
||||||
t.Fatalf("can't locate origin DIE at off %v", ooff)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Name should check out.
|
|
||||||
name, ok := originDIE.Val(dwarf.AttrName).(string)
|
|
||||||
if !ok {
|
|
||||||
t.Fatalf("no name attr for inlined subroutine at offset %v", child.Offset)
|
|
||||||
}
|
|
||||||
if name != "main.inlined" {
|
|
||||||
t.Fatalf("expected inlined routine %s got %s", "main.cand", name)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Verify that the call_file attribute for the inlined
|
|
||||||
// instance is ok. In this case it should match the file
|
|
||||||
// for the main routine. To do this we need to locate the
|
|
||||||
// compilation unit DIE that encloses what we're looking
|
|
||||||
// at; this can be done with the examiner.
|
|
||||||
cf, cfOK := child.Val(dwarf.AttrCallFile).(int64)
|
|
||||||
if !cfOK {
|
|
||||||
t.Fatalf("no call_file attr for inlined subroutine at offset %v", child.Offset)
|
|
||||||
}
|
|
||||||
file, err := ex.FileRef(d, mainIdx, cf)
|
|
||||||
if err != nil {
|
|
||||||
t.Errorf("FileRef: %v", err)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
base := filepath.Base(file)
|
|
||||||
if base != callFile {
|
|
||||||
t.Errorf("bad call_file attribute, found '%s', want '%s'",
|
|
||||||
file, callFile)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Verify that the call_line attribute for the inlined
|
|
||||||
// instance is ok.
|
|
||||||
cl, clOK := child.Val(dwarf.AttrCallLine).(int64)
|
|
||||||
if !clOK {
|
|
||||||
t.Fatalf("no call_line attr for inlined subroutine at offset %v", child.Offset)
|
|
||||||
}
|
|
||||||
if cl != callLine {
|
|
||||||
t.Errorf("bad call_line attribute, found %d, want %d", cl, callLine)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if !found {
|
for _, tc := range tests {
|
||||||
t.Fatalf("not enough inlined subroutines found in main.main")
|
tc := tc
|
||||||
|
t.Run(tc.name, func(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
// Note: this is a build with "-l=4", as opposed to "-l -N". The
|
||||||
|
// test is intended to verify DWARF that is only generated when
|
||||||
|
// the inliner is active. We're only going to look at the DWARF for
|
||||||
|
// main.main, however, hence we build with "-gcflags=-l=4" as opposed
|
||||||
|
// to "-gcflags=all=-l=4".
|
||||||
|
d, ex := gobuildAndExamine(t, tc.prog, OptInl4)
|
||||||
|
|
||||||
|
maindie := findSubprogramDIE(t, ex, "main.main")
|
||||||
|
|
||||||
|
// Walk main's children and pick out the inlined subroutines
|
||||||
|
mainIdx := ex.IdxFromOffset(maindie.Offset)
|
||||||
|
childDies := ex.Children(mainIdx)
|
||||||
|
found := false
|
||||||
|
for _, child := range childDies {
|
||||||
|
if child.Tag != dwarf.TagInlinedSubroutine {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// Found an inlined subroutine.
|
||||||
|
if found {
|
||||||
|
t.Fatalf("Found multiple inlined subroutines, expect only one")
|
||||||
|
}
|
||||||
|
found = true
|
||||||
|
|
||||||
|
// Locate abstract origin.
|
||||||
|
ooff, originOK := child.Val(dwarf.AttrAbstractOrigin).(dwarf.Offset)
|
||||||
|
if !originOK {
|
||||||
|
t.Fatalf("no abstract origin attr for inlined subroutine at offset %v", child.Offset)
|
||||||
|
}
|
||||||
|
originDIE := ex.EntryFromOffset(ooff)
|
||||||
|
if originDIE == nil {
|
||||||
|
t.Fatalf("can't locate origin DIE at off %v", ooff)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Name should check out.
|
||||||
|
name, ok := originDIE.Val(dwarf.AttrName).(string)
|
||||||
|
if !ok {
|
||||||
|
t.Fatalf("no name attr for inlined subroutine at offset %v", child.Offset)
|
||||||
|
}
|
||||||
|
if name != "main.inlined" {
|
||||||
|
t.Fatalf("expected inlined routine %s got %s", "main.cand", name)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verify that the call_file attribute for the inlined
|
||||||
|
// instance is ok. In this case it should match the file
|
||||||
|
// for the main routine. To do this we need to locate the
|
||||||
|
// compilation unit DIE that encloses what we're looking
|
||||||
|
// at; this can be done with the examiner.
|
||||||
|
cf, cfOK := child.Val(dwarf.AttrCallFile).(int64)
|
||||||
|
if !cfOK {
|
||||||
|
t.Fatalf("no call_file attr for inlined subroutine at offset %v", child.Offset)
|
||||||
|
}
|
||||||
|
file, err := ex.FileRef(d, mainIdx, cf)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("FileRef: %v", err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
base := filepath.Base(file)
|
||||||
|
if base != tc.file {
|
||||||
|
t.Errorf("bad call_file attribute, found '%s', want '%s'",
|
||||||
|
file, tc.file)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verify that the call_line attribute for the inlined
|
||||||
|
// instance is ok.
|
||||||
|
cl, clOK := child.Val(dwarf.AttrCallLine).(int64)
|
||||||
|
if !clOK {
|
||||||
|
t.Fatalf("no call_line attr for inlined subroutine at offset %v", child.Offset)
|
||||||
|
}
|
||||||
|
if cl != tc.line {
|
||||||
|
t.Errorf("bad call_line attribute, found %d, want %d", cl, tc.line)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !found {
|
||||||
|
t.Fatalf("not enough inlined subroutines found in main.main")
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user