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: missing debug information for return values of runtime functions #48573
Comments
This might be related to #46845. |
CC @thanm |
Thanks. As mentioned in #46845, when you build with With that said, it seems odd that the return params are missing entirely (as opposed to being present, but not having accurate location expressions). I'll take a look and see if I can figure out what the issue is. |
Ping from the release team: any updates? This is marked as a release blocker. |
Thanks for the ping. Hadn't realized that this had been marked as a release blocker (is there a way to be notified when this happens?). I'll see about taking a look later this week. |
Some background material on this bug: When optimization is turned on, the DWARF-gen code that emits variable and formal_parameter DIEs draws info from two places: the SSA name table, and the "Dcl" slice for the function (code here), which has entries for in and out parameters and locals for the function. The general rule is that if a variable is SSA-able, it will get entered into the SSA name table, and will be incorporated into the DWARF by the locationlists code. If a var is not in the SSA name table, then dwarfgen will pick it up from the "Dcl" slice for the function. Here's an example function:
For this function "x" and "s" are passed in register, "b" and "unusedParam" are passed on the stack. At SSA construction time, the "Dcl" slice for function foo will contain entries for all of the vars above, e.g.
After we enter SSA and optimization starts, the back end will optimize things away, remove dead code, etc, until we arrive at the "stackframe" SSA pass. This pass sorts locals by size and assigns concrete offsets to things in the stack frame, and will prune away autos from the Dcl list that are no longer referenced (code here). The upshot is that if a variable gets pruned by "stackframe" because it is unused (and also doesn't appear in the SSA name table) then we don't emit a DWARF DIE for it (as with "unusedLocal" above). During the register ABI work, a change was made in CL 302071 to "stackframe" to treat register-resident output parameter (PARAMOUT) variables that same as locals, which meant that if they were unused, we'd delete them from the "Dcl" slice. The second thing that happened during the register ABI work is that we changed the code emitted by the back end for "return" statements changed. Whereas before a statement like
would be lowered to a store into the PARAMOUT variable (e.g. "~r0"), with the register ABI turned on this code would be lowered into a "MakeResult" op, which doesn't refer to the PARAMOUT variable at all. Bottom line is that we now skip PARAMOUT vars during DWARF variable DIE generation unless they are not register-resident, since they no longer appear either the SSA name table or the "Dcl" slice. There are a couple of different ways we could fix this bug. One possibility would be to just cache away a copy of the pre-optimization "Dcl" slice and use that as a way to pick up PARAMOUT nodes. A second possibility would be to move away from using the "Dcl" slice entirely, and instead operate off the function signature type itself (since the optimizer is not going to be messing with that). The one pothole/wrinkle there is that the DWARF param/var DIE includes DeclLine and DeclFile attributes, and we can't get that sort of info just from the signature type. |
Change https://golang.org/cl/362618 mentions this issue: |
What version of Go are you using (
go version
)?Does this issue reproduce with the latest release?
yes
What operating system and processor architecture are you using (
go env
)?go env
OutputWhat did you do?
Build an application with the Go 1.17 toolchain using command
go build -gcflags=all="-N -l" HelloWorld.go
:The DWARF information for Go functions defined in the runtime package does not contain
DW_TAG_formal_parameter
entries for return values. I have checked multiple runtime functions, for all of them I see the same problem. As an example let's checkruntime.mapaccess2
which has the following signature:func mapaccess2(t *maptype, h *hmap, key unsafe.Pointer) (unsafe.Pointer, bool)
What did you expect to see?
DW_TAG_formal_parameter
entries for the two return values ofruntime.mapaccess2
If I build the program with Go 1.16.8 toolchain the return value entries exist:
DWARF Go 1.16.8
debug_1_16_8.txt:
What did you see instead?
With Go 1.17 toolchain the return value entries are missing:
DWARF Go 1.17
debug.txt:
The text was updated successfully, but these errors were encountered: