runtime: bad frame pointer during panic during duffcopy #73748
Labels
BugReport
Issues describing a possible bug in the Go implementation.
compiler/runtime
Issues related to the Go compiler and/or runtime.
NeedsInvestigation
Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.
Milestone
Go version
go version go1.23.8 linux/amd64
Output of
go env
in your module/workspace:What did you do?
This is split off from #73664.
I ran the following program (Playground link):
Instead of
trace.Log
, we could do some blocking with the block profiler enabled. The important thing is that we try to record a traceback using frame pointer unwinding during the panic.What did you see happen?
Crashed during frame pointer unwinding on amd64:
On arm64, the program doesn't crash, but the stack trace for the
trace.Log
call is wrong:Note that this doesn't fail or produce invalid results with optimizations disabled (
-gcflags=-N
)What did you expect to see?
No crash. This also reproduces with Go 1.24.3.
I believe the issue is due to the way the frame pointer is set up around
runtime.duffcopy
calls. Since those calls jump into the middle of a function, the compiler sets up a pseudo-frame around the calls instead. On both amd64 and arm64, the compiler saves a frame pointer below the current stack frame without changing the stack pointer:amd64 example:
arm64 example:
If the copy panics, for example due to a nil pointer dereference, then the panic function call is injected into the goroutine using its current stack. The panic call frame will clobber the frame pointer saved by duffcopy since it's below the current call frame. On arm64 we end up with a frame pointer loop and on amd64 we end up with junk.
https://go.dev/cl/672996 would fix this by getting rid of the code to save a frame pointer. Alternatively, we could make an actual stack frame, but that could be wasteful?
cc @randall77
The text was updated successfully, but these errors were encountered: