Skip to content

Commit

Permalink
debug/gosym: read start line of a function from gopclntab
Browse files Browse the repository at this point in the history
This field was introduced in go 1.20 therefore we need to safeguard it
to only be read for pclntabs of that version or higher, as otherwise
nonsensical bytes would be read. The fallback is now the default value
of 0.

Fixes golang#58474
  • Loading branch information
brancz committed Mar 4, 2023
1 parent b94dc38 commit 7f5f178
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 0 deletions.
7 changes: 7 additions & 0 deletions src/debug/gosym/pclntab.go
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,9 @@ func (t *LineTable) go12Funcs() []Func {
}()
}

// The start line only exists in pclntab starting at version 1.20.
readStartLine := t.version >= ver120

ft := t.funcTab()
funcs := make([]Func, ft.Count())
syms := make([]Sym, len(funcs))
Expand All @@ -309,6 +312,9 @@ func (t *LineTable) go12Funcs() []Func {
f.Entry = ft.pc(i)
f.End = ft.pc(i + 1)
info := t.funcData(uint32(i))
if readStartLine {
f.StartLine = int(info.startLine())
}
f.LineTable = t
f.FrameSize = int(info.deferreturn())
syms[i] = Sym{
Expand Down Expand Up @@ -461,6 +467,7 @@ func (f funcData) deferreturn() uint32 { return f.field(3) }
func (f funcData) pcfile() uint32 { return f.field(5) }
func (f funcData) pcln() uint32 { return f.field(6) }
func (f funcData) cuOffset() uint32 { return f.field(8) }
func (f funcData) startLine() uint32 { return f.field(9) }

// field returns the nth field of the _func struct.
// It panics if n == 0 or n > 9; for n == 0, call f.entryPC.
Expand Down
18 changes: 18 additions & 0 deletions src/debug/gosym/pclntab_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,24 @@ func TestLineAline(t *testing.T) {
}
}

func TestStartLine(t *testing.T) {
dotest(t)
defer endtest()

f, tab := crack(pclinetestBinary, t)
defer f.Close()

sym := tab.LookupFunc("main.main")
wantLine := 6
if sym == nil {
t.Fatal("no main.main")
}

if sym.StartLine != wantLine {
t.Fatalf("StartLine = %d, want %d", sym.StartLine, wantLine)
}
}

func TestPCLine(t *testing.T) {
dotest(t)
defer endtest()
Expand Down
1 change: 1 addition & 0 deletions src/debug/gosym/symtab.go
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,7 @@ type Func struct {
FrameSize int
LineTable *LineTable
Obj *Obj
StartLine int
}

// An Obj represents a collection of functions in a symbol table.
Expand Down

0 comments on commit 7f5f178

Please sign in to comment.