-
Notifications
You must be signed in to change notification settings - Fork 17.8k
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 DWARF location lists for return values #50990
Comments
CC @thanm |
I took a look. I think things are working mostly as intended, within the limitations we have as part of our compiler design and how things work with optimization turned on. The DWARF variable location expressions emitted by the compiler when optimization is on are basically "best effort" at the moment -- we do our best to emit correct DWARF when we can, but there are going to be cases where the optimizer will confuse the DWARF emitter and it can't generate anything reasonable (or anything at all), and other cases where we miss variables completely. The incoming Go code looks like:
The assembly we generate looks like this:
The "+" tag on line (+9) on the first instruction indicates that this spot is marked in the DWARF line table as being the start of a statement (hence this is where the debugger will stop). Semantics for Go return parameters are that they initially have a zero value, then take on other values if assigned to by name or by a return statement. In this case at line 9, the return hasn't yet executed, so there is no specific location we can point to (register or memory) that contains the value we need for a variable like "d". There are compilers out there that will recognize portions of the lifetime of a variable that are constant, and emit multi-range location expressions where some of the ranges hold locations (register or stack) and other ranges hold constants (GCC does a pretty good job of this). The Go compiler currently doesn't try to do this, since it adds complexity to the value tracking machinery. If it can't see a specific register or chunk of memory that holds the value of a named variable, it won't emit a debug location for it. It's true that once the "MOVQ CX, AX" has executed, then we have a concrete location for "d", so we could generate a location list that started at that spot. It's not clear how useful that would be, however, since the only way to get to that spot is to step instruction by instruction (something most users of debuggers are not going to do). For return parameters in general I think the Go compiler has always done a pretty substandard job, even with the register ABI. Prior to the register ABI work, it would simply put out a location description pointing the stack location and be done with it. So for a function like
If you were to stop on SPOT1 or SPOT2 above, printing "d" would just show an incorrect value of zero. When the register ABI work was completed, there were a lot more opportunities during late call lowing for return params to get "lost in the sauce", which is what's happening now in many cases. So just to summarize: yes, we could definitely be doing better in terms of emitting DWARF location expressions for return params, but fixing this is something that would require some concerted design and implementation work, it isn't a case where we could resolve the issue with small tweaks to the existing code. |
What version of Go are you using (
go version
)?Does this issue reproduce with the latest release?
With Go1.17.6, DWARF entries for return values of optimized functions were not available at all due to related issue #48573
What operating system and processor architecture are you using (
go env
)?go env
OutputWhat did you do?
Build an application with the Go 1.18beta2 toolchain using the command
go build Main.go
(optimized binary):Disassembly of `main.testFunc`
What did you expect to see?
DWARF location lists for function return values:
Example for return value `d`
What did you see instead?
Missing DWARF location lists for all function return values of
main.testFunc
:DWARF data of main.testFunc
debug.txt
I have checked many functions of optimized binaries, for all of them I can see the same problem.
Thanks
The text was updated successfully, but these errors were encountered: