From 368cbeb0bcc5528151846caede33b802a826d2ea Mon Sep 17 00:00:00 2001 From: aarzilli Date: Mon, 23 Jul 2018 17:54:50 +0200 Subject: [PATCH] dwarf/line: remove foundFile "optimization" from LineToPC There is no guarantee that files will end up stored contiguously in the debug_line section which makes this optimization wrong in the general case. In particular with recent versions of go1.11 and a go.mod file present the go compiler seems to sometimes produce executables that actually violate this assumption. --- pkg/dwarf/line/state_machine.go | 21 ++++++--------------- pkg/proc/proc.go | 2 +- 2 files changed, 7 insertions(+), 16 deletions(-) diff --git a/pkg/dwarf/line/state_machine.go b/pkg/dwarf/line/state_machine.go index 27408860..d97f682b 100644 --- a/pkg/dwarf/line/state_machine.go +++ b/pkg/dwarf/line/state_machine.go @@ -264,10 +264,7 @@ func (lineInfo *DebugLineInfo) LineToPC(filename string, lineno int) uint64 { return 0 } - var ( - foundFile bool - sm = newStateMachine(lineInfo, lineInfo.Instructions) - ) + sm := newStateMachine(lineInfo, lineInfo.Instructions) // if no instruction marked is_stmt is found fallback to the first // instruction assigned to the filename:line. @@ -280,17 +277,11 @@ func (lineInfo *DebugLineInfo) LineToPC(filename string, lineno int) uint64 { } break } - if foundFile && sm.file != filename { - break - } - if sm.line == lineno && sm.file == filename { - foundFile = true - if sm.valid { - if sm.isStmt { - return sm.address - } else if fallbackPC == 0 { - fallbackPC = sm.address - } + if sm.line == lineno && sm.file == filename && sm.valid { + if sm.isStmt { + return sm.address + } else if fallbackPC == 0 { + fallbackPC = sm.address } } } diff --git a/pkg/proc/proc.go b/pkg/proc/proc.go index 3404eb0c..88bbd11b 100644 --- a/pkg/proc/proc.go +++ b/pkg/proc/proc.go @@ -640,7 +640,7 @@ func FirstPCAfterPrologue(p Process, fn *Function, sameline bool) (uint64, error // breakpoint with file:line and with the function name always result on // the same instruction being selected. entryFile, entryLine := fn.cu.lineInfo.PCToLine(fn.Entry, fn.Entry) - if pc, _, err := p.BinInfo().LineToPC(entryFile, entryLine); err == nil { + if pc, _, err := p.BinInfo().LineToPC(entryFile, entryLine); err == nil && pc >= fn.Entry && pc < fn.End { return pc, nil } } -- GitLab