proc, terminal: use DW_AT_producer to warn user about optimized code
This commit is contained in:
parent
07c716818e
commit
4f813b8101
@ -72,6 +72,7 @@ type compileUnit struct {
|
|||||||
Name string // univocal name for non-go compile units
|
Name string // univocal name for non-go compile units
|
||||||
lineInfo *line.DebugLineInfo // debug_line segment associated with this compile unit
|
lineInfo *line.DebugLineInfo // debug_line segment associated with this compile unit
|
||||||
LowPC, HighPC uint64
|
LowPC, HighPC uint64
|
||||||
|
optimized bool // this compile unit is optimized
|
||||||
}
|
}
|
||||||
|
|
||||||
// Function describes a function in the target program.
|
// Function describes a function in the target program.
|
||||||
@ -126,6 +127,11 @@ func (fn *Function) BaseName() string {
|
|||||||
return fn.Name
|
return fn.Name
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Optimized returns true if the function was optimized by the compiler.
|
||||||
|
func (fn *Function) Optimized() bool {
|
||||||
|
return fn.cu.optimized
|
||||||
|
}
|
||||||
|
|
||||||
type constantsMap map[dwarf.Offset]*constantType
|
type constantsMap map[dwarf.Offset]*constantType
|
||||||
|
|
||||||
type constantType struct {
|
type constantType struct {
|
||||||
|
@ -204,6 +204,10 @@ func (bi *BinaryInfo) loadDebugInfoMaps(debugLineBytes []byte, wg *sync.WaitGrou
|
|||||||
if lineInfoOffset >= 0 && lineInfoOffset < int64(len(debugLineBytes)) {
|
if lineInfoOffset >= 0 && lineInfoOffset < int64(len(debugLineBytes)) {
|
||||||
cu.lineInfo = line.Parse(compdir, bytes.NewBuffer(debugLineBytes[lineInfoOffset:]))
|
cu.lineInfo = line.Parse(compdir, bytes.NewBuffer(debugLineBytes[lineInfoOffset:]))
|
||||||
}
|
}
|
||||||
|
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")
|
||||||
|
}
|
||||||
bi.compileUnits = append(bi.compileUnits, cu)
|
bi.compileUnits = append(bi.compileUnits, cu)
|
||||||
|
|
||||||
case dwarf.TagArrayType, dwarf.TagBaseType, dwarf.TagClassType, dwarf.TagStructType, dwarf.TagUnionType, dwarf.TagConstType, dwarf.TagVolatileType, dwarf.TagRestrictType, dwarf.TagEnumerationType, dwarf.TagPointerType, dwarf.TagSubroutineType, dwarf.TagTypedef, dwarf.TagUnspecifiedType:
|
case dwarf.TagArrayType, dwarf.TagBaseType, dwarf.TagClassType, dwarf.TagStructType, dwarf.TagUnionType, dwarf.TagConstType, dwarf.TagVolatileType, dwarf.TagRestrictType, dwarf.TagEnumerationType, dwarf.TagPointerType, dwarf.TagSubroutineType, dwarf.TagTypedef, dwarf.TagUnspecifiedType:
|
||||||
|
@ -23,6 +23,8 @@ import (
|
|||||||
"github.com/derekparker/delve/service/debugger"
|
"github.com/derekparker/delve/service/debugger"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const optimizedFunctionWarning = "Warning: debugging optimized function"
|
||||||
|
|
||||||
type cmdPrefix int
|
type cmdPrefix int
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -1353,6 +1355,9 @@ func printcontextThread(t *Term, th *api.Thread) {
|
|||||||
|
|
||||||
if th.Breakpoint == nil {
|
if th.Breakpoint == nil {
|
||||||
fmt.Printf("> %s() %s:%d (PC: %#v)\n", fn.Name, ShortenFilePath(th.File), th.Line, th.PC)
|
fmt.Printf("> %s() %s:%d (PC: %#v)\n", fn.Name, ShortenFilePath(th.File), th.Line, th.PC)
|
||||||
|
if th.Function != nil && th.Function.Optimized {
|
||||||
|
fmt.Println(optimizedFunctionWarning)
|
||||||
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1391,6 +1396,9 @@ func printcontextThread(t *Term, th *api.Thread) {
|
|||||||
th.Breakpoint.TotalHitCount,
|
th.Breakpoint.TotalHitCount,
|
||||||
th.PC)
|
th.PC)
|
||||||
}
|
}
|
||||||
|
if th.Function != nil && th.Function.Optimized {
|
||||||
|
fmt.Println(optimizedFunctionWarning)
|
||||||
|
}
|
||||||
|
|
||||||
if th.BreakpointInfo != nil {
|
if th.BreakpointInfo != nil {
|
||||||
bp := th.Breakpoint
|
bp := th.Breakpoint
|
||||||
|
@ -212,10 +212,11 @@ func ConvertFunction(fn *proc.Function) *Function {
|
|||||||
// those fields is not documented their value was replaced with 0 when
|
// those fields is not documented their value was replaced with 0 when
|
||||||
// gosym.Func was replaced by debug_info entries.
|
// gosym.Func was replaced by debug_info entries.
|
||||||
return &Function{
|
return &Function{
|
||||||
Name: fn.Name,
|
Name: fn.Name,
|
||||||
Type: 0,
|
Type: 0,
|
||||||
Value: fn.Entry,
|
Value: fn.Entry,
|
||||||
GoType: 0,
|
GoType: 0,
|
||||||
|
Optimized: fn.Optimized(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -148,6 +148,8 @@ type Function struct {
|
|||||||
Value uint64 `json:"value"`
|
Value uint64 `json:"value"`
|
||||||
Type byte `json:"type"`
|
Type byte `json:"type"`
|
||||||
GoType uint64 `json:"goType"`
|
GoType uint64 `json:"goType"`
|
||||||
|
// Optimized is true if the function was optimized
|
||||||
|
Optimized bool `json:"optimized"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// VariableFlags is the type of the Flags field of Variable.
|
// VariableFlags is the type of the Flags field of Variable.
|
||||||
|
Loading…
Reference in New Issue
Block a user