mirror of
https://github.com/go-delve/delve.git
synced 2025-10-29 01:27:16 +08:00
dwarf,proc: various fixes to support DWARFv5 (#3893)
Miscellaneous fixes to our DWARFv5 implementation, several contributed by @thanm.
This commit is contained in:
committed by
GitHub
parent
1df310a2e3
commit
e6e7aeb667
@ -116,7 +116,11 @@ func Parse(compdir string, buf *bytes.Buffer, debugLineStr []byte, logfn func(st
|
||||
// - dbl.Prologue.UnitLength is the length of the entire unit, not including the 4 bytes to represent that length.
|
||||
// - dbl.Prologue.Length is the length of the prologue not including unit length, version or prologue length itself.
|
||||
// - So you have UnitLength - PrologueLength - (version_length_bytes(2) + prologue_length_bytes(4)).
|
||||
dbl.Instructions = buf.Next(int(dbl.Prologue.UnitLength - dbl.Prologue.Length - 6))
|
||||
verDelta := uint32(6)
|
||||
if dbl.Prologue.Version >= 5 {
|
||||
verDelta = uint32(8)
|
||||
}
|
||||
dbl.Instructions = buf.Next(int(dbl.Prologue.UnitLength - dbl.Prologue.Length - verDelta))
|
||||
|
||||
return dbl
|
||||
}
|
||||
|
||||
@ -63,6 +63,7 @@ const (
|
||||
lineRangeGo18 uint8 = 10
|
||||
versionGo14 uint16 = 2
|
||||
versionGo111 uint16 = 3
|
||||
versionGo125 uint16 = 5
|
||||
opcodeBaseGo14 uint8 = 10
|
||||
opcodeBaseGo111 uint8 = 11
|
||||
)
|
||||
@ -79,7 +80,7 @@ func testDebugLinePrologueParser(p string, t *testing.T) {
|
||||
for _, dbl := range debugLines {
|
||||
prologue := dbl.Prologue
|
||||
|
||||
if prologue.Version != versionGo14 && prologue.Version != versionGo111 {
|
||||
if prologue.Version != versionGo14 && prologue.Version != versionGo111 && prologue.Version != versionGo125 {
|
||||
t.Fatal("Version not parsed correctly", prologue.Version)
|
||||
}
|
||||
|
||||
|
||||
@ -106,7 +106,7 @@ func newStateMachine(dbl *DebugLineInfo, instructions []byte, ptrSize int) *Stat
|
||||
}
|
||||
var file string
|
||||
if len(dbl.FileNames) > 0 {
|
||||
file = dbl.FileNames[0].Path
|
||||
file = dbl.defaultFile()
|
||||
}
|
||||
dbl.endSeqIsValid = true
|
||||
sm := &StateMachine{
|
||||
@ -123,6 +123,22 @@ func newStateMachine(dbl *DebugLineInfo, instructions []byte, ptrSize int) *Stat
|
||||
return sm
|
||||
}
|
||||
|
||||
func (dbl *DebugLineInfo) defaultFile() string {
|
||||
// The default file is always file 1, however DWARFv5 starts numbering the
|
||||
// entries of the files table from 0 but prior versions started with 1
|
||||
// which means that for DWARFv4 and earlier the default file is the first
|
||||
// entry of the table where in DWARFv5 the default is the second entry.
|
||||
// See DWARFv4 and DWARFv5 section 6.2.4 at the end.
|
||||
if dbl.Prologue.Version < 5 {
|
||||
return dbl.FileNames[0].Path
|
||||
}
|
||||
if len(dbl.FileNames) == 1 {
|
||||
// DWARFv5 doesn't say what should happen in this case.
|
||||
return dbl.FileNames[0].Path
|
||||
}
|
||||
return dbl.FileNames[1].Path
|
||||
}
|
||||
|
||||
// AllPCsForFileLines Adds all PCs for a given file and set (domain of map) of lines
|
||||
// to the map value corresponding to each line.
|
||||
func (lineInfo *DebugLineInfo) AllPCsForFileLines(f string, m map[int][]uint64) {
|
||||
@ -390,7 +406,7 @@ func (sm *StateMachine) next() error {
|
||||
}
|
||||
if sm.endSeq {
|
||||
sm.endSeq = false
|
||||
sm.file = sm.dbl.FileNames[0].Path
|
||||
sm.file = sm.dbl.defaultFile()
|
||||
sm.line = 1
|
||||
sm.column = 0
|
||||
sm.isa = 0
|
||||
|
||||
@ -131,7 +131,7 @@ func ReadUnitVersions(data []byte) map[dwarf.Offset]uint8 {
|
||||
|
||||
switch unitType {
|
||||
case _DW_UT_compile, _DW_UT_partial:
|
||||
headerSize = 5 + secoffsz
|
||||
headerSize = 4 + secoffsz
|
||||
|
||||
case _DW_UT_skeleton, _DW_UT_split_compile:
|
||||
headerSize = 4 + secoffsz + 8
|
||||
|
||||
@ -42,7 +42,7 @@ import (
|
||||
|
||||
const (
|
||||
dwarfGoLanguage = 22 // DW_LANG_Go (from DWARF v5, section 7.12, page 231)
|
||||
dwarfAttrAddrBase = 0x74 // debug/dwarf.AttrAddrBase in Go 1.14, defined here for compatibility with Go < 1.14
|
||||
dwarfAttrAddrBase = 0x73 // debug/dwarf.AttrAddrBase in Go 1.14, defined here for compatibility with Go < 1.14
|
||||
dwarfTreeCacheSize = 512 // size of the dwarfTree cache of each image
|
||||
)
|
||||
|
||||
|
||||
@ -136,7 +136,7 @@ func TestDwarfVersion(t *testing.T) {
|
||||
const fakeEntryPoint = 1
|
||||
assertNoError(bi.LoadBinaryInfo(fixture.Path, fakeEntryPoint, nil), t, "LoadBinaryInfo")
|
||||
for _, cu := range bi.Images[0].compileUnits {
|
||||
if cu.Version != 4 {
|
||||
if cu.Version != 4 && cu.Version != 5 {
|
||||
t.Errorf("compile unit %q at %#x has bad version %d", cu.name, cu.entry.Offset, cu.Version)
|
||||
}
|
||||
}
|
||||
|
||||
@ -720,13 +720,13 @@ func TestStacktrace(t *testing.T) {
|
||||
locations, err := proc.ThreadStacktrace(p, p.CurrentThread(), 40)
|
||||
assertNoError(err, t, "Stacktrace()")
|
||||
|
||||
if len(locations) != len(stacks[i])+2 {
|
||||
t.Fatalf("Wrong stack trace size %d %d\n", len(locations), len(stacks[i])+2)
|
||||
}
|
||||
|
||||
t.Logf("Stacktrace %d:\n", i)
|
||||
for i := range locations {
|
||||
t.Logf("\t%s:%d\n", locations[i].Call.File, locations[i].Call.Line)
|
||||
t.Logf("\t%s (%#x) %s:%d\n", locations[i].Call.Fn.Name, locations[i].Call.PC, locations[i].Call.File, locations[i].Call.Line)
|
||||
}
|
||||
|
||||
if len(locations) != len(stacks[i])+2 {
|
||||
t.Fatalf("Wrong stack trace size %d %d\n", len(locations), len(stacks[i])+2)
|
||||
}
|
||||
|
||||
for j := range stacks[i] {
|
||||
@ -3193,6 +3193,7 @@ func testDeclLineCount(t *testing.T, p *proc.Target, lineno int, tgtvars []strin
|
||||
|
||||
assertLineNumber(p, t, lineno, "Program did not continue to correct next location")
|
||||
scope, err := proc.GoroutineScope(p, p.CurrentThread())
|
||||
t.Logf("scope PC: %#x\n", scope.PC)
|
||||
assertNoError(err, t, fmt.Sprintf("GoroutineScope (:%d)", lineno))
|
||||
vars, err := scope.Locals(0, "")
|
||||
assertNoError(err, t, fmt.Sprintf("Locals (:%d)", lineno))
|
||||
|
||||
Reference in New Issue
Block a user