From 4f813b81013fcd1bef4a980b78e7fe19cdc2adfe Mon Sep 17 00:00:00 2001 From: aarzilli Date: Fri, 27 Oct 2017 17:00:41 +0200 Subject: [PATCH] proc, terminal: use DW_AT_producer to warn user about optimized code --- pkg/proc/bininfo.go | 6 ++++++ pkg/proc/types.go | 4 ++++ pkg/terminal/command.go | 8 ++++++++ service/api/conversions.go | 9 +++++---- service/api/types.go | 2 ++ 5 files changed, 25 insertions(+), 4 deletions(-) diff --git a/pkg/proc/bininfo.go b/pkg/proc/bininfo.go index 1a411187..d7b7c50f 100644 --- a/pkg/proc/bininfo.go +++ b/pkg/proc/bininfo.go @@ -72,6 +72,7 @@ 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 } // Function describes a function in the target program. @@ -126,6 +127,11 @@ func (fn *Function) BaseName() string { 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 constantType struct { diff --git a/pkg/proc/types.go b/pkg/proc/types.go index c6378f40..114cd5db 100644 --- a/pkg/proc/types.go +++ b/pkg/proc/types.go @@ -204,6 +204,10 @@ func (bi *BinaryInfo) loadDebugInfoMaps(debugLineBytes []byte, wg *sync.WaitGrou if lineInfoOffset >= 0 && lineInfoOffset < int64(len(debugLineBytes)) { 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) 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: diff --git a/pkg/terminal/command.go b/pkg/terminal/command.go index ff8e5b6e..6d2ca864 100644 --- a/pkg/terminal/command.go +++ b/pkg/terminal/command.go @@ -23,6 +23,8 @@ import ( "github.com/derekparker/delve/service/debugger" ) +const optimizedFunctionWarning = "Warning: debugging optimized function" + type cmdPrefix int const ( @@ -1353,6 +1355,9 @@ func printcontextThread(t *Term, th *api.Thread) { if th.Breakpoint == nil { 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 } @@ -1391,6 +1396,9 @@ func printcontextThread(t *Term, th *api.Thread) { th.Breakpoint.TotalHitCount, th.PC) } + if th.Function != nil && th.Function.Optimized { + fmt.Println(optimizedFunctionWarning) + } if th.BreakpointInfo != nil { bp := th.Breakpoint diff --git a/service/api/conversions.go b/service/api/conversions.go index 36c3123d..8745cad3 100644 --- a/service/api/conversions.go +++ b/service/api/conversions.go @@ -212,10 +212,11 @@ func ConvertFunction(fn *proc.Function) *Function { // those fields is not documented their value was replaced with 0 when // gosym.Func was replaced by debug_info entries. return &Function{ - Name: fn.Name, - Type: 0, - Value: fn.Entry, - GoType: 0, + Name: fn.Name, + Type: 0, + Value: fn.Entry, + GoType: 0, + Optimized: fn.Optimized(), } } diff --git a/service/api/types.go b/service/api/types.go index 3bcba150..a6ce44ba 100644 --- a/service/api/types.go +++ b/service/api/types.go @@ -148,6 +148,8 @@ type Function struct { Value uint64 `json:"value"` Type byte `json:"type"` 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. -- GitLab