diff options
| author | Than McIntosh <thanm@google.com> | 2017-10-23 11:41:47 -0400 |
|---|---|---|
| committer | Than McIntosh <thanm@google.com> | 2017-10-23 19:19:25 +0000 |
| commit | 87f83eac7ffd54cc4fe56e4d4f22680ffdb071a1 (patch) | |
| tree | c57c6e3304e2a91b6d5bfd9d24c1129ef3f12781 | |
| parent | 0316d6618c7a986727c9e99fb7aab7c7a4e92d71 (diff) | |
| download | go-87f83eac7ffd54cc4fe56e4d4f22680ffdb071a1.tar.xz | |
cmd/compile: include non-decomposed vars for -dwarflocationlists
When enhanced DWARF location list generation is enabled (via internal
option -dwarflocationlists), variable entries were missing for "large"
(non-decomposable) locals and formals. From the debugging perspective,
this makes it appear that the variable doesn't exist, which is
probably not what we want. This change insures that a formal/local DIE
is created for these vars (with correct type, line, etc) but with a
conservative ("no info") location.
Change-Id: I10b2e9a51a60c7b4c748e987cdec5f2d8b2837d5
Reviewed-on: https://go-review.googlesource.com/72630
Run-TryBot: Than McIntosh <thanm@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Heschi Kreinick <heschi@google.com>
| -rw-r--r-- | src/cmd/compile/internal/gc/pgen.go | 39 |
1 files changed, 37 insertions, 2 deletions
diff --git a/src/cmd/compile/internal/gc/pgen.go b/src/cmd/compile/internal/gc/pgen.go index 9a91fe40ce..eaaf56f385 100644 --- a/src/cmd/compile/internal/gc/pgen.go +++ b/src/cmd/compile/internal/gc/pgen.go @@ -338,7 +338,7 @@ func debuginfo(fnsym *obj.LSym, curfn interface{}) []dwarf.Scope { var dwarfVars []*dwarf.Var var decls []*Node if Ctxt.Flag_locationlists && Ctxt.Flag_optimize { - decls, dwarfVars = createComplexVars(fnsym, debugInfo) + decls, dwarfVars = createComplexVars(fnsym, debugInfo, automDecls) } else { decls, dwarfVars = createSimpleVars(automDecls) } @@ -416,7 +416,7 @@ type varPart struct { slot ssa.SlotID } -func createComplexVars(fnsym *obj.LSym, debugInfo *ssa.FuncDebug) ([]*Node, []*dwarf.Var) { +func createComplexVars(fnsym *obj.LSym, debugInfo *ssa.FuncDebug, automDecls []*Node) ([]*Node, []*dwarf.Var) { for _, blockDebug := range debugInfo.Blocks { for _, locList := range blockDebug.Variables { for _, loc := range locList.Locations { @@ -438,11 +438,13 @@ func createComplexVars(fnsym *obj.LSym, debugInfo *ssa.FuncDebug) ([]*Node, []*d // Group SSA variables by the user variable they were decomposed from. varParts := map[*Node][]varPart{} + ssaVars := make(map[*Node]bool) for slotID, slot := range debugInfo.VarSlots { for slot.SplitOf != nil { slot = slot.SplitOf } n := slot.N.(*Node) + ssaVars[n] = true varParts[n] = append(varParts[n], varPart{varOffset(slot), ssa.SlotID(slotID)}) } @@ -472,6 +474,39 @@ func createComplexVars(fnsym *obj.LSym, debugInfo *ssa.FuncDebug) ([]*Node, []*d vars = append(vars, dvar) } } + + // The machinery above will create a dwarf.Var for only those + // variables that are decomposed into SSA names. Fill in the list + // with entries for the remaining variables (including things too + // big to decompose). Since optimization is enabled, the recipe + // below creates a conservative location. The idea here is that we + // want to communicate to the user that "yes, there is a variable + // named X in this function, but no, I don't have enough + // information to reliably report its contents." + for _, n := range automDecls { + if _, found := ssaVars[n]; !found { + continue + } + c := n.Sym.Name[0] + if c == '~' || c == '.' { + continue + } + typename := dwarf.InfoPrefix + typesymname(n.Type) + decls = append(decls, n) + abbrev := dwarf.DW_ABRV_AUTO_LOCLIST + if n.Class() == PPARAM || n.Class() == PPARAMOUT { + abbrev = dwarf.DW_ABRV_PARAM_LOCLIST + } + vars = append(vars, &dwarf.Var{ + Name: n.Sym.Name, + IsReturnValue: n.Class() == PPARAMOUT, + Abbrev: abbrev, + StackOffset: int32(n.Xoffset), + Type: Ctxt.Lookup(typename), + DeclLine: n.Pos.Line(), + }) + } + return decls, vars } |
