]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: adjust inlined DW_AT_call_line by //line
authorMichael Pratt <mpratt@google.com>
Wed, 22 Feb 2023 22:50:20 +0000 (17:50 -0500)
committerGopher Robot <gobot@golang.org>
Thu, 23 Feb 2023 22:08:33 +0000 (22:08 +0000)
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>
src/cmd/compile/internal/dwarfgen/dwinl.go
src/cmd/link/internal/ld/dwarf_test.go

index c785e064a7f48497b2f4304848efe5879c65cd33..99e1ce9a81aa8266c6d9aa9f50d8010272ae7cb4 100644 (file)
@@ -273,13 +273,13 @@ func insertInlCall(dwcalls *dwarf.InlCalls, inlIdx int, imap map[int]int) int {
        // Create new entry for this inline
        inlinedFn := base.Ctxt.InlTree.InlinedFunction(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)
-       pb := base.Ctxt.PosTable.Pos(callXPos).Base()
-       callFileSym := base.Ctxt.Lookup(pb.SymFilename())
        ic := dwarf.InlCall{
                InlIndex:  inlIdx,
                CallFile:  callFileSym,
-               CallLine:  uint32(callXPos.Line()),
+               CallLine:  uint32(callPos.RelLine()),
                AbsFunSym: absFnSym,
                Root:      parCallIdx == -1,
        }
index 17ed44ad6a2b7be7ce86e1b7a979d883891f56e1..6fac85a01d8140c2c50441e1129bdecc831b48ca 100644 (file)
@@ -530,91 +530,113 @@ func inlined() int {
        return notinlined()
 }
 
+%s
 func main() {
        x := inlined()
        G = x
 }
 `
-       // 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, prog, OptInl4)
+       tests := []struct {
+               name string
+               prog string
+               file string // basename
+               line int64
+       }{
+               {
+                       name: "normal",
+                       prog: fmt.Sprintf(prog, ""),
+                       file: "test.go",
+                       line: 17,
+               },
+               {
+                       name: "line-directive",
+                       prog: fmt.Sprintf(prog, "//line /foobar.go:200"),
+                       file: "foobar.go",
+                       line: 201,
+               },
+       }
+       for _, tc := range tests {
+               tc := tc
+               t.Run(tc.name, func(t *testing.T) {
+                       t.Parallel()
 
-       const (
-               callFile = "test.go" // basename
-               callLine = 16
-       )
+                       // 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")
+                       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
-               }
+                       // 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
+                               // 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)
-               }
+                               // 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)
-               }
+                               // 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_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 != callLine {
-                       t.Errorf("bad call_line attribute, found %d, want %d", cl, callLine)
-               }
-       }
-       if !found {
-               t.Fatalf("not enough inlined subroutines found in main.main")
+                               // 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")
+                       }
+               })
        }
 }