pkg/dwarf/line: Fix parsing file table for DWARFv5 (#3090)

As we parse this informatin in the loop we must take care to assemble
things correctly. In this situation when we encounter a file name,
the dir index is -1, then subsequently we get the correct dir index
for that file and can put them together. Previously we were adding the
file and then the directory location to the file list instead of
correctly concatenating them, resulting in an incorrect file list making
indexing into the list return incorrect results later on.
This commit is contained in:
Derek Parker 2022-08-05 10:16:38 -07:00 committed by GitHub
parent be08778975
commit b83ea0c2fa
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 31 additions and 15 deletions

@ -279,11 +279,16 @@ func parseFileEntries5(info *DebugLineInfo, buf *bytes.Buffer) bool {
fileCount, _ := util.DecodeULEB128(buf)
info.FileNames = make([]*FileEntry, 0, fileCount)
for i := 0; i < int(fileCount); i++ {
var (
p string
diridx int
entry = new(FileEntry)
)
fileEntryFormReader.reset()
for fileEntryFormReader.next(buf) {
entry := new(FileEntry)
var p string
var diridx int
diridx = -1
switch fileEntryFormReader.contentType {
@ -306,17 +311,6 @@ func parseFileEntries5(info *DebugLineInfo, buf *bytes.Buffer) bool {
case _DW_LNCT_MD5:
// not implemented
}
if info.normalizeBackslash {
p = strings.ReplaceAll(p, "\\", "/")
}
if diridx >= 0 && !pathIsAbs(p) && diridx < len(info.IncludeDirs) {
p = path.Join(info.IncludeDirs[diridx], p)
}
entry.Path = p
info.FileNames = append(info.FileNames, entry)
info.Lookup[entry.Path] = entry
}
if fileEntryFormReader.err != nil {
if info.Logf != nil {
@ -324,6 +318,16 @@ func parseFileEntries5(info *DebugLineInfo, buf *bytes.Buffer) bool {
}
return false
}
if diridx >= 0 && diridx < len(info.IncludeDirs) {
p = path.Join(info.IncludeDirs[diridx], p)
}
if info.normalizeBackslash {
p = strings.ReplaceAll(p, "\\", "/")
}
entry.Path = p
info.FileNames = append(info.FileNames, entry)
info.Lookup[entry.Path] = entry
}
return true
}

@ -231,7 +231,7 @@ func (lineInfo *DebugLineInfo) stateMachineFor(basePC, pc uint64) *StateMachine
sm = newStateMachine(lineInfo, lineInfo.Instructions, lineInfo.ptrSize)
} else {
// Try to use the last state machine that we used for this function, if
// there isn't one or it's already past pc try to clone the cached state
// there isn't one, or it's already past pc try to clone the cached state
// machine stopped at the entry point of the function.
// As a last resort start from the start of the debug_line section.
sm = lineInfo.lastMachineCache[basePC]

@ -849,6 +849,18 @@ func TestCGONext(t *testing.T) {
})
}
func TestCGOBreakpointLocation(t *testing.T) {
protest.MustHaveCgo(t)
protest.AllowRecording(t)
withTestProcess("cgotest", t, func(p *proc.Target, fixture protest.Fixture) {
bp := setFunctionBreakpoint(p, t, "C.foo")
if !strings.Contains(bp.File, "cgotest.go") {
t.Fatalf("incorrect breakpoint location, expected cgotest.go got %s", bp.File)
}
})
}
type loc struct {
line int
fn string