Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cmd/compile: DWARF variable info includes compiler temporaries #16338

Closed
thanm opened this issue Jul 12, 2016 · 10 comments
Closed

cmd/compile: DWARF variable info includes compiler temporaries #16338

thanm opened this issue Jul 12, 2016 · 10 comments
Labels
FrozenDueToAge NeedsFix The path to resolution is known, but the work has not been done.
Milestone

Comments

@thanm
Copy link
Contributor

thanm commented Jul 12, 2016

Please answer these questions before submitting your issue. Thanks!

  1. What version of Go are you using (go version)?

go version devel +5701174

  1. What operating system and processor architecture are you using (go env)?

GOARCH="amd64"
GOOS="linux"

  1. What did you do?

While debugging a problem in a toy go application that I'm writing, I noticed an issue with the debug/DWARF being generated for one of the subroutines I was looking at.

Specifically, the .debug_info seems to contain variables + locations for compiler temporaries -- this not what I would have expected. Here is a reproducer:

% go get github.com/thanm/gccgo-demangler/gccgo-dem
% cd $GOPATH/src/github.com/thanm/gccgo-demangler/gccgo-dem
% git checkout ceda66eb429a9750e4fc56059455f9a5006e131a
% go build .
% gdb gccgo-dem
...
(gdb) b 'github.com/thanm/gccgo-demangler/demangler.dem_struct'
Breakpoint 1 at 0x46fee0: file ... demangler.go, line 139.
(gdb) run -i testdata/driver.go.dump.ast
...
(gdb) b 200
Breakpoint 2 at 0x470d8d: file ... /demangler.go, line 200.
(gdb) c
...

At this point in the GDB session if you issue an "info args" command, the resulting info looks fine:

(gdb) info args
id = []uint8 = {83 'S', 52 '4', 95 '', 114 'r', 101 'e', 115 's', 48 '0',
78 'N', 51 '3', 95 '
', 105 'i', 110 'n', 116 't', 52 '4', 95 '', 114 'r',
101 'e', 115 's', 49 '1', 78 'N', 53 '5', 95 '
', 101 'e', 114 'r', 114 'r',
111 'o', 114 'r', 101 'e'}
res = []uint8 = {64 '@'}
consumed = 32
err = {tab = 0x8, data = 0x10}

The story is not so good for local variables:

(gdb) info locals
len = 4
idx = 27
i = 2
len = 5
cap = 22
ftcons = 8
len = 842350941560
cap = 842350941576
fncons = 6
len = 4
cap = 29
len = 2
cap = 16
len = 0
cap = 16
len = 2
cap = 16
ptr = 0xc4200ca2a3 "res1N5_errore)"
ptr = 0xc4200ca2aa "errore)"
itab = 0xc420075678 "\270V\a", <incomplete sequence \304>
data = 0x43cf9e <runtime.slicebytetostring+126> "H\213D$@h\211D$xH\213D$8H\211\204$\200"
itab = 0x0
data = 0x0
ptr = 0xc4200aafa9 "5"
itab = 0x0
data = 0x0
ptr = 0xc4200ca2a3 "res1N5_errore)"
ptr = []uint8 * = {105 'i', 110 'n', 116 't'}
ptr = []uint8 *<error reading variable: Cannot access memory at address 0x8>
ptr = []uint8 * = {114 'r', 101 'e', 115 's', 48 '0'}
(gdb)

First problem is that some of the local variables (ex: fieldnames) that should be in scope are not present in the output (I verified with readelf --debug-dump that they are missing from the DWARF).

Second problem is that there seem to be a lot of compiler-generated temporary variables showing up instead (ex: itab, ptr, data, ...). This is a bit unfriendly, also will add a lot of bloat to the DWARF.

@josharian
Copy link
Contributor

This might be intentional. (Hard to tell from the bug report alone, and I'm on my phone.) See https://go-review.googlesource.com/21233 for some context.

@ianlancetaylor ianlancetaylor changed the title debug/dwarf: issues with variable locations cmd/compile: issues with variable locations Jul 12, 2016
@ianlancetaylor ianlancetaylor added this to the Go1.8Maybe milestone Jul 12, 2016
@randall77
Copy link
Contributor

@derekparker

@thanm
Copy link
Contributor Author

thanm commented Jul 14, 2016

Delve: cool!

However this is not an issue for "dlv debug", since it is compiling things with "-N -l". DWARF looks fine in that case:

 <1><1c53f>: Abbrev Number: 2 (DW_TAG_subprogram)
    <1c540>   DW_AT_name        : github.com/thanm/gccgo-demangler/demangler.dem_struct 
    <1c576>   DW_AT_low_pc      : 0x470e00  
    <1c57e>   DW_AT_high_pc     : 0x4727d0  
    <1c586>   DW_AT_external    : 1 
...
 <2><1c6b1>: Abbrev Number: 4 (DW_TAG_variable)
    <1c6b2>   DW_AT_name        : fieldnames    
    <1c6bd>   DW_AT_location    : 5 byte block: 9c 11 b0 72 22  (DW_OP_call_frame_cfa; DW_OP_consts: -1744; DW_OP_plus)
    <1c6c3>   DW_AT_type        : <0x4529b> 

For "dlv exec" run on regular go-compiled binary I see the same as gdb, e.g. "could not find symbol value" for the local slice/string variables that have been split, plus the clutter/cruft for all of the split fields (ptr, len, etc).

For regular compiles with optimization it seems that there isn't much point emitting location expressions for locals corresponding to split components of strings, slices, etc. At least that's how I see it.

I will experiment and see if I can come up with a patch that suppresses the DW_TAG_variable's DIEs for these vars. Might be interesting.

@quentinmit quentinmit added the NeedsFix The path to resolution is known, but the work has not been done. label Oct 10, 2016
@rsc
Copy link
Contributor

rsc commented Oct 20, 2016

Some variables being missing seems almost unavoidable at least in some cases. But certainly all these crazy temporaries should go away.

@rsc rsc modified the milestones: Go1.9, Go1.8Maybe Oct 20, 2016
@rsc rsc changed the title cmd/compile: issues with variable locations cmd/compile: DWARF variable info includes compiler temporaries Oct 20, 2016
@gopherbot
Copy link

CL https://golang.org/cl/31662 mentions this issue.

@thanm
Copy link
Contributor Author

thanm commented Oct 21, 2016

I have a tentative fix for this issue ; who would be the right person to review my changes?

@ianlancetaylor
Copy link
Contributor

I think @mdempsky will eat anything.

@mdempsky
Copy link
Member

I think @mdempsky will eat anything.

Except for animals. ;)

@gopherbot
Copy link

CL https://golang.org/cl/31819 mentions this issue.

@mdempsky
Copy link
Member

It looks like the easiest thing to do is to just use the bare symbol in the obj.ATYPE instruction generated in pgen.go:

                case PPARAM, PPARAMOUT:
                        p := Gins(obj.ATYPE, n, nil)
+                       p.From.Sym = obj.Linklookup(Ctxt, n.Sym.Name, 0)
                        p.To.Type = obj.TYPE_MEM
                        p.To.Name = obj.NAME_EXTERN
                        p.To.Sym = Linksym(ngotype(n))

Then we can just get rid of the "Drop the package prefix from locals and arguments" logic in cmd/internal/dwarf.PutFunc.

This would also drop the package prefix for Plan 9's acid debug info. That actually seems desirable to me (e.g., a local variable "foo" would actually appear as "foo" rather than "path/to/pkg.foo"), but I thought I'd point it out anyway in case anyone knows a reason that would be bad. /cc @0intro

@mikioh mikioh modified the milestones: Go1.8, Go1.9 Oct 30, 2016
@golang golang locked and limited conversation to collaborators Oct 30, 2017
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
FrozenDueToAge NeedsFix The path to resolution is known, but the work has not been done.
Projects
None yet
Development

No branches or pull requests

9 participants