-
Notifications
You must be signed in to change notification settings - Fork 18k
runtime/debug: PrintStack function prints incorrect stack information in go1.21.0 #62132
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
CC @golang/runtime. |
You mean two The two |
@liuzengh for next time, please paste output as text, instead of image. Thanks. |
Yes, I mean two Ok, I will paste output as text for next issue. This is my first time opening an issue for golang, I hope you don't mind. |
I was just about to report this issue as well. I made reproduction here. Compare Go output from Go 1.20 and 1.21. I noticed this because my errors package tests started failing with Go 1.21. I check for how stack trace is formatted there. I do not mind so much that |
Are you sure this is the same? #60324 talks about the change from |
I'm certainly happy to reopen this if it's a different issue, but I'm not sure I follow your argument for why it's not the same. Here's the original example with names so I can refer to the closures: func TestRuntimeDebugPrintStack(t *testing.T) {
err := func() error { // F1
return func() error { // F2
return func() error { // F3
return func() error { // F4
debug.PrintStack()
return newMyErr(11, "TestTraceErrorSetStackSkip error")
}()
}()
}()
}()
require.NotNil(t, err)
} In Go 1.21, we started more aggressively inlining functions that themselves constructed closures. Prior to Go 1.21, none of these got inlined, and thus we see their "original" names based on hierarchical numbering in the traceback. In Go 1.21, F1 gets inlined into F2's pre-inlined name is func TestRuntimeDebugPrintStack(t *testing.T) {
F1()
}
func F1() error { // F1
return func() error { // F2
return func() error { // F3
return func() error { // F4
debug.PrintStack()
return nil
}()
}()
}()
} If we run this, we get:
Here we can again see that F1 got inlined into Finally we can get to the crux of what's going on: recall that in the original example, the original name of F2 is These inlining breadcrumbs are what we're discussing in #60324. This happens to be a good example of where the current convention has somewhat odd, verbose, and unexpected results. (Sorry that got rather long! I was also convincing myself that it's in fact the same issue 😅) |
I see. Thanks for detailed explanation. To me the confusing thing is that the number of function names shown changes between:
and
I can understand that how names are formatted changes. Or that one name inherits the name from another function. But how could the number of functions change? I think I get it now. Thanks. |
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?
I write a unit test:
What did you see?
There are two TestRuntimeDebugPrintStack appearing.
Original Screenshot
What did you expect to see?
But only one TestRuntimeDebugPrintStack is expected. I expect to see a result similar to the following in go version go1.20.4 darwin/arm64.
Original Screenshot
The text was updated successfully, but these errors were encountered: