-
Notifications
You must be signed in to change notification settings - Fork 18k
cmd/compile: misleading panic on deferred func #29797
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
Comments
In #16011, the line number in the panic points off the end of the function (it points at the line containing only |
The current behavior is that we return the line number of the So the line number seems right here, at least with respect to how we currently define "right". |
I'd be less fussed about the specific line number if there were some other indication in the stack trace that deferred functions were running. In my original example, the panic is largely indistinguishable between the cases of the global |
We might be able to show |
I'm opposed to just reporting the line number of the defer. If you do:
Currently we report the line number of the So I'm opposed to just changing the line number. In the case of a defer of nil, we could report the Fundamentally the problem is there are 2 line numbers we'd like to report. Possibly we could print both line numbers?
Currently this prints:
Maybe it could print:
(Needs a better layout, but that's the idea.) |
At runtime we'd just need to grab the parent pc to record in the defer structure. It shouldn't be terribly expensive, but it does mean defers are that much slower, when we have #14939 to fix. |
If you ask me, this new format might confuse people (and maybe some tools that parse stack output). Maybe just keep existing format, but print both
Also paging @aarzilli in case it affects delve in some way. @aarzilli do you have any bright suggestions on what to do here? Thank you. Alex |
what's the "parent pc"? the PC of the defer statement is already recorded in _defer. When you encounter runtime.jmpdefer in a traceback you could print that instead and the stacktrace would reflect better what's going on, like in @alexbrainman's example. |
Although, now that I think about it, in that particular example:
neither runtime.jmpdefer nor runtime.deferreturn are left on the stack, so it would probably be much harder to do. But it would work for the OP. |
Indeed, so it wouldn't cost any extra at runtime.
Yes, the nil defer case is easier. |
Do you keep a list of those? If you do, I'd like to know because delve uses the disassembler for this (we need them for a different thing). |
@aarzilli We don't, but we could keep track. We could keep a linked list in the G of all the frames that are currently in a deferreturn, and possibly what the pc of the defer call was. |
@randall77, does this need to be addressed for 1.12, or should we milestone it to 1.13 or Unplanned? |
This issue has been present for many releases. Moving to 1.13. |
What version of Go are you using (
go version
)?What did you do?
https://play.golang.org/p/3aP7yqgWXdf
What did you expect to see?
The panic stack trace should point to where a nil pointer was dereferenced.
What did you see instead?
The panic stack trace pointed at an innocent line.
This is pretty similar to #14646 and #16011. The panic points at a line that is clearly quite capable of yielding that panic, so it led me on a wild goose chase. It took using gdb (gasp!) to figure out that the defer was involved. Consider this an argument for revisiting the "working as intended" judgment on #16011; it was a bug in my code, but the stack trace was very confusing.
If there was a way to indicate that the deferred function was being executed I would have spotted the issue earlier. The regular stack trace does not indicate that. gdb, however, shows
runtime.jmpdefer
as the immediate stack frame, which is how I figured it out.The text was updated successfully, but these errors were encountered: