From cac86b879197f49f3c45f4557a5a5cef2941eb11 Mon Sep 17 00:00:00 2001 From: Derek Parker Date: Mon, 20 Feb 2023 11:36:09 +0200 Subject: [PATCH] dwarf/line: handle end_seq properly (#3277) This patch changes how we handle end_seq in the debug_line state machine program. Instead of always considering the state machine invalid at the end_seq instead simply consider the *current* address invalid. This solves a number of issues such as incorrect disassemble output for the last few instructions in certain functions, and creating an eval scope at an address within the last few instructions of certain functions. It also handles the case where the end_seq address is the same as the start address of the next adjacent function, which would previously confuse Delve which is why we initially marked end_seq as invalid for the entire state machine. This approach is more nuanced and still solves that initial problem while fixing some problems introduced by that patch. --- pkg/dwarf/line/state_machine.go | 7 ++++--- pkg/proc/eval.go | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/pkg/dwarf/line/state_machine.go b/pkg/dwarf/line/state_machine.go index c7d1b65d..6c31fb46 100644 --- a/pkg/dwarf/line/state_machine.go +++ b/pkg/dwarf/line/state_machine.go @@ -108,6 +108,7 @@ func newStateMachine(dbl *DebugLineInfo, instructions []byte, ptrSize int) *Stat if len(dbl.FileNames) > 0 { file = dbl.FileNames[0].Path } + dbl.endSeqIsValid = true sm := &StateMachine{ dbl: dbl, file: file, @@ -261,7 +262,7 @@ func (sm *StateMachine) PCToLine(pc uint64) (string, int, bool) { if (sm.address > pc) && (pc >= sm.lastAddress) { return sm.lastFile, sm.lastLine, true } - if sm.address == pc { + if sm.address == pc && !sm.endSeq { return sm.file, sm.line, true } } @@ -272,7 +273,7 @@ func (sm *StateMachine) PCToLine(pc uint64) (string, int, bool) { break } } - if sm.valid { + if sm.valid && !sm.endSeq { return sm.file, sm.line, true } return "", 0, false @@ -301,7 +302,7 @@ func (lineInfo *DebugLineInfo) LineToPCs(filename string, lineno int) []PCStmt { } break } - if sm.line == lineno && sm.file == filename && sm.valid { + if sm.line == lineno && sm.file == filename && sm.valid && !sm.endSeq { pcstmts = append(pcstmts, PCStmt{sm.address, sm.isStmt}) } } diff --git a/pkg/proc/eval.go b/pkg/proc/eval.go index d8348fe6..1afa2294 100644 --- a/pkg/proc/eval.go +++ b/pkg/proc/eval.go @@ -474,7 +474,7 @@ func (scope *EvalScope) LocalVariables(cfg LoadConfig) ([]*Variable, error) { // FunctionArguments returns the name, value, and type of all current function arguments. func (scope *EvalScope) FunctionArguments(cfg LoadConfig) ([]*Variable, error) { - vars, err := scope.Locals(localsNoDeclLineCheck) + vars, err := scope.Locals(0) if err != nil { return nil, err }