Join GitHub today
GitHub is home to over 40 million developers working together to host and review code, manage projects, and build software together.Sign up
runtime: TestCallersDeferNilFuncPanic failed in generating traceback (linux/arm64) #36050
What version of Go are you using (
Yes, that is fine.
Posting the full stack trace that the program fails with would help.
It would be nice to find a way to get the test to fail by itself. If it fails during a GC interrupt (probably, but hard to tell without the full error log), using GOGC=1 will help tickle that bug. Also running the test in multiple goroutines simultaneously might also help.
goroutine 35 [running]:
goroutine 1 [chan receive, locked to thread]:
goroutine 2 [force gc (idle)]:
goroutine 3 [GC sweep wait]:
goroutine 4 [GC scavenge wait]:
goroutine 18 [finalizer wait]:
@shawn-xdji thanks for the bug report and the stack trace.
I can reproduce this always with debug compilation of the individual runtime test on a linux-arm64 gomote:
The issue is that we are calling gentraceback() with a callback in order to look for the next open-coded defer frame to process in the panic case. But calling gentraceback() with a callback on arm64 (lr architectures) throws an error if jmpdefer is on the stack (because jmpdefer register manipulation is non-atomic). This only happens in the one case where the defer pointer is null, since then there is a seg fault on the jmpdefer instruction that jumps though the defer pointer. Also, it only happens if stack-allocated defers are used (since open-coded defers don't use jmpdefer), hence why this only happens when debug flags are enabled.
The simplest fix is to force the seg fault to happen in deferreturn() just before the jmpdefer(). This will cause one extra load in cases when jmpdefer is used, but that is now rare, since stack-allocated defers are now rare.
Thanks a lot @danscales , I could reproduce the issue using your command line.
Just out of curiosity, why setting GO_GCFLAGS failed to reproduce the issue?
Both the following two work fine.
GO_GCFLAGS=all='-N -l' go test -run=TestCallersDeferNilFuncPanic runtime