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: some local variables are missing from DWARF #18247

Open
alandonovan opened this issue Dec 8, 2016 · 11 comments
Open

cmd/compile: some local variables are missing from DWARF #18247

alandonovan opened this issue Dec 8, 2016 · 11 comments
Labels
compiler/runtime Issues related to the Go compiler and/or runtime. Debugging
Milestone

Comments

@alandonovan
Copy link
Contributor

alandonovan commented Dec 8, 2016

$ cat a.go
package main

func f(x int) {
        s := "string"
        for i := 0; i < x; i++ {
                println(i, s)
        }
}

func main() {
        f(10)
}
$ go build a.go
$ readelf -w a
...
 <1><1530f>: Abbrev Number: 2 (DW_TAG_subprogram)
    <15310>   DW_AT_name        : main.f        
    <15317>   DW_AT_low_pc      : 0x44cd50      
    <1531f>   DW_AT_high_pc     : 0x44cde4      
    <15327>   DW_AT_external    : 1     
 <2><15328>: Abbrev Number: 4 (DW_TAG_variable)
    <15329>   DW_AT_name        : i     
    <1532b>   DW_AT_location    : 4 byte block: 9c 11 68 22     (DW_OP_call_frame_cfa; DW_OP_consts: -24; DW_OP_plus)
    <15330>   DW_AT_type        : <0x16c15>     
 <2><15338>: Abbrev Number: 5 (DW_TAG_formal_parameter)
    <15339>   DW_AT_name        : x     
    <1533b>   DW_AT_location    : 1 byte block: 9c      (DW_OP_call_frame_cfa)
    <1533d>   DW_AT_type        : <0x16c15>     
 <2><15345>: Abbrev Number: 0
...

For function f, gc emits debug information about the formal parameter x and the local variable i, but not the local variable s. In this instance I imagine the reason is that s is effectively constant, but still it would improve the debug view if such variables were included. And in other programs, many other locals that are truly variable are omitted too.

(Is there a simple explanation for how the compiler currently decides which variables get a DW_TAG_variable record?)

@alandonovan
Copy link
Contributor Author

cc: @hyangah

@ianlancetaylor ianlancetaylor changed the title gc: some local variables are missing from DWARF cmd/compile: some local variables are missing from DWARF Dec 8, 2016
@ianlancetaylor
Copy link
Contributor

CC @randall77 @josharian @mdempsky

@ianlancetaylor ianlancetaylor added this to the Go1.9Maybe milestone Dec 8, 2016
@mdempsky
Copy link
Member

mdempsky commented Dec 8, 2016

(Is there a simple explanation for how the compiler currently decides which variables get a DW_TAG_variable record?)

I believe the simple explanation is we emit DWARF records for parameters (including result parameters) and for user-declared local variables that are allocated stack frame space.

@alandonovan
Copy link
Contributor Author

Ah, thanks. So variable that are constant, are allocated to registers, are CSE'd, or escape to the heap will be missing from the debug view.

@mdempsky
Copy link
Member

mdempsky commented Dec 8, 2016

Oh, if a variable v escapes to heap, we don't emit DWARF records for v itself, but we will emit them for a synthesized &v pointer variable. There are also cases like if we decompose a composite type like string, you'll end up with separate s.len and s.ptr variables instead of a single s.

But I believe your other cases are correct: registerized and CSE'd variables are not mentioned in the DWARF output.

If it would help, I think we can easily emit records to at least declare that those variables exist in the source (e.g., so debuggers looking up an identifier don't mistakenly find a shadowed global variable instead). We're just not currently setup to track location any more fine-grained than a simple stack frame offset, so we can't emit DW_AT_location for them.

@aclements
Copy link
Member

But I believe your other cases are correct: registerized and CSE'd variables are not mentioned in the DWARF output.

Furthermore, if a variable is allocated a stack slot but is registerized at a particular PC, the DWARF information will only refer to the stack slot, so you can get a stale (or uninitialized?) value. Fixing that is probably part of fixing debug info for fully registerized variables. But now that the DWARF is being emitted by the compiler instead of the linker, there's at least a hope of doing this.

@bcmills
Copy link
Contributor

bcmills commented Jan 31, 2017

I've also noticed that at some points in program execution, running info locals in GDB produces a giant dump of package-level variables. I'm not able to find a consistent repro with the current master branch, though; has that part of the DWARF info been fixed recently?

@mdempsky
Copy link
Member

@bcmills I can't think of any significant recent DWARF changes that would have that effect.

@bradfitz bradfitz modified the milestones: Go1.9Maybe, Go1.10 Jul 20, 2017
@mdempsky mdempsky modified the milestones: Go1.10, Go1.11 Nov 30, 2017
@mdempsky
Copy link
Member

Would it be preferable that instead of emitting DWARF entries for the pseudo-variable &v, that we instead emit a DWARF entry for v using DW_OP_deref or whatever?

@aclements
Copy link
Member

Would it be preferable that instead of emitting DWARF entries for the pseudo-variable &v, that we instead emit a DWARF entry for v using DW_OP_deref or whatever?

Yes, definitely. :)

@gopherbot gopherbot modified the milestones: Go1.11, Unplanned May 23, 2018
@gopherbot gopherbot added the compiler/runtime Issues related to the Go compiler and/or runtime. label Jul 13, 2022
@ajwerner
Copy link

Update: as of go1.21.5, there is now an entry for s. The function main.f generally gets inlined, but whether you suppress that with go:noline or not, there is an entry for s. The location is empty as opposed to the location in memory of the string, but that could be worthy of a separate issue.

0x00062530:     DW_TAG_variable
                  DW_AT_name    ("s")
                  DW_AT_decl_line       (5)
                  DW_AT_type    (0x000000000004d624 "string")
                  DW_AT_location        (<empty>)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
compiler/runtime Issues related to the Go compiler and/or runtime. Debugging
Projects
None yet
Development

No branches or pull requests

9 participants