proc: correctly set G struct offset for 1.11
The offset of G changed in go1.11 from 0x8a0 to 0x30. See: https://github.com/golang/go/issues/23617
This commit is contained in:
parent
5155ef047f
commit
42747a0951
@ -161,3 +161,18 @@ func VersionAfterOrEqual(version string, major, minor int) bool {
|
||||
}
|
||||
return ver.AfterOrEqual(GoVersion{major, minor, -1, 0, 0, ""})
|
||||
}
|
||||
|
||||
const producerVersionPrefix = "Go cmd/compile "
|
||||
|
||||
// ProducerAfterOrEqual checks that the DW_AT_producer version is
|
||||
// major.minor or a later version, or a development version.
|
||||
func ProducerAfterOrEqual(producer string, major, minor int) bool {
|
||||
if strings.HasPrefix(producer, producerVersionPrefix) {
|
||||
producer = producer[len(producerVersionPrefix):]
|
||||
}
|
||||
ver, _ := Parse(producer)
|
||||
if ver.IsDevel() {
|
||||
return true
|
||||
}
|
||||
return ver.AfterOrEqual(GoVersion{major, minor, -1, 0, 0, ""})
|
||||
}
|
||||
|
||||
@ -21,6 +21,7 @@ import (
|
||||
"github.com/derekparker/delve/pkg/dwarf/line"
|
||||
"github.com/derekparker/delve/pkg/dwarf/op"
|
||||
"github.com/derekparker/delve/pkg/dwarf/reader"
|
||||
"github.com/derekparker/delve/pkg/goversion"
|
||||
)
|
||||
|
||||
type BinaryInfo struct {
|
||||
@ -75,7 +76,8 @@ type compileUnit struct {
|
||||
Name string // univocal name for non-go compile units
|
||||
lineInfo *line.DebugLineInfo // debug_line segment associated with this compile unit
|
||||
LowPC, HighPC uint64
|
||||
optimized bool // this compile unit is optimized
|
||||
optimized bool // this compile unit is optimized
|
||||
producer string // producer attribute
|
||||
}
|
||||
|
||||
type partialUnitConstant struct {
|
||||
@ -365,7 +367,7 @@ func (bi *BinaryInfo) LoadFromData(dwdata *dwarf.Data, debugFrameBytes, debugLin
|
||||
|
||||
bi.loclistInit(debugLocBytes)
|
||||
|
||||
bi.loadDebugInfoMaps(debugLineBytes, nil)
|
||||
bi.loadDebugInfoMaps(debugLineBytes, nil, nil)
|
||||
}
|
||||
|
||||
func (bi *BinaryInfo) loclistInit(data []byte) {
|
||||
@ -440,6 +442,15 @@ func (bi *BinaryInfo) findCompileUnit(pc uint64) *compileUnit {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (bi *BinaryInfo) Producer() string {
|
||||
for _, cu := range bi.compileUnits {
|
||||
if cu.isgo && cu.producer != "" {
|
||||
return cu.producer
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// ELF ///////////////////////////////////////////////////////////////
|
||||
|
||||
func (bi *BinaryInfo) LoadBinaryInfoElf(path string, wg *sync.WaitGroup) error {
|
||||
@ -470,7 +481,7 @@ func (bi *BinaryInfo) LoadBinaryInfoElf(path string, wg *sync.WaitGroup) error {
|
||||
|
||||
wg.Add(3)
|
||||
go bi.parseDebugFrameElf(elfFile, wg)
|
||||
go bi.loadDebugInfoMaps(debugLineBytes, wg)
|
||||
go bi.loadDebugInfoMaps(debugLineBytes, wg, nil)
|
||||
go bi.setGStructOffsetElf(elfFile, wg)
|
||||
return nil
|
||||
}
|
||||
@ -582,7 +593,7 @@ func (bi *BinaryInfo) LoadBinaryInfoPE(path string, wg *sync.WaitGroup) error {
|
||||
|
||||
wg.Add(2)
|
||||
go bi.parseDebugFramePE(peFile, wg)
|
||||
go bi.loadDebugInfoMaps(debugLineBytes, wg)
|
||||
go bi.loadDebugInfoMaps(debugLineBytes, wg, nil)
|
||||
|
||||
// Use ArbitraryUserPointer (0x28) as pointer to pointer
|
||||
// to G struct per:
|
||||
@ -750,11 +761,22 @@ func (bi *BinaryInfo) LoadBinaryInfoMacho(path string, wg *sync.WaitGroup) error
|
||||
|
||||
wg.Add(2)
|
||||
go bi.parseDebugFrameMacho(exe, wg)
|
||||
go bi.loadDebugInfoMaps(debugLineBytes, wg)
|
||||
bi.gStructOffset = 0x8a0
|
||||
go bi.loadDebugInfoMaps(debugLineBytes, wg, bi.setGStructOffsetMacho)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (bi *BinaryInfo) setGStructOffsetMacho() {
|
||||
// In go1.11 it's 0x30, before 0x8a0, see:
|
||||
// https://github.com/golang/go/issues/23617
|
||||
// and go commit b3a854c733257c5249c3435ffcee194f8439676a
|
||||
producer := bi.Producer()
|
||||
if producer != "" && goversion.ProducerAfterOrEqual(producer, 1, 11) {
|
||||
bi.gStructOffset = 0x30
|
||||
return
|
||||
}
|
||||
bi.gStructOffset = 0x8a0
|
||||
}
|
||||
|
||||
func (bi *BinaryInfo) parseDebugFrameMacho(exe *macho.File, wg *sync.WaitGroup) {
|
||||
defer wg.Done()
|
||||
|
||||
|
||||
@ -178,7 +178,7 @@ func (v packageVarsByAddr) Len() int { return len(v) }
|
||||
func (v packageVarsByAddr) Less(i int, j int) bool { return v[i].addr < v[j].addr }
|
||||
func (v packageVarsByAddr) Swap(i int, j int) { v[i], v[j] = v[j], v[i] }
|
||||
|
||||
func (bi *BinaryInfo) loadDebugInfoMaps(debugLineBytes []byte, wg *sync.WaitGroup) {
|
||||
func (bi *BinaryInfo) loadDebugInfoMaps(debugLineBytes []byte, wg *sync.WaitGroup, cont func()) {
|
||||
if wg != nil {
|
||||
defer wg.Done()
|
||||
}
|
||||
@ -220,9 +220,15 @@ func (bi *BinaryInfo) loadDebugInfoMaps(debugLineBytes []byte, wg *sync.WaitGrou
|
||||
cu.lineInfo = line.Parse(compdir, bytes.NewBuffer(debugLineBytes[lineInfoOffset:]))
|
||||
cu.lineInfo.LogSuppressedErrors(logflags.DebugLineErrors())
|
||||
}
|
||||
if producer, _ := entry.Val(dwarf.AttrProducer).(string); cu.isgo && producer != "" {
|
||||
semicolon := strings.Index(producer, ";")
|
||||
cu.optimized = semicolon < 0 || !strings.Contains(producer[semicolon:], "-N") || !strings.Contains(producer[semicolon:], "-l")
|
||||
cu.producer, _ = entry.Val(dwarf.AttrProducer).(string)
|
||||
if cu.isgo {
|
||||
semicolon := strings.Index(cu.producer, ";")
|
||||
if semicolon < 0 {
|
||||
cu.optimized = true
|
||||
} else {
|
||||
cu.optimized = !strings.Contains(cu.producer[semicolon:], "-N") || !strings.Contains(cu.producer[semicolon:], "-l")
|
||||
cu.producer = cu.producer[:semicolon]
|
||||
}
|
||||
}
|
||||
bi.compileUnits = append(bi.compileUnits, cu)
|
||||
|
||||
@ -395,6 +401,10 @@ func (bi *BinaryInfo) loadDebugInfoMaps(debugLineBytes []byte, wg *sync.WaitGrou
|
||||
}
|
||||
sort.Strings(bi.Sources)
|
||||
bi.Sources = uniq(bi.Sources)
|
||||
|
||||
if cont != nil {
|
||||
cont()
|
||||
}
|
||||
}
|
||||
|
||||
func uniq(s []string) []string {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user