https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114582
--- Comment #1 from Ian Lance Taylor <ian at airs dot com> --- The bug here, and also with PR 114581, is in unwinding from a signal call. A simplified version of the code for this issue is: func main() { defer func() { recover() }() f() } func f() { *p = 0 } The *p = 0 in f will raise a SIGSEGV. The Go runtime will turn that into a panic. The recover in main will prevent that panic from killing the program. The unwind code works by walking up the stack until it finds a recover. When it finds a recover, it records that stack frame as the end of the unwind. It runs the recover, then walks up the stack again to unwind it. In the second walk, it checks that it does not walk past the stack frame that calls recover. Recording the stack frame is done based on what the signal handler calls the CFA, which is, basically, the frame pointer. It is also based on whether a signal occurred in that frame. In this test case, the function f is so simple that it has no frame. That turns out to mean that f's CFA is the same as main's CFA. In the first stack walk, we find main, and record main's CFA as the point where the second unwind should stop. In the second stack walk, when we get to f, we think we have reached the end. But we haven't, because we haven't reached main yet. This causes an assert, which shows up as a SIGABRT. That is what happens today. But it would work fine if we knew that a signal occurred in f, as in fact it did. However, we don't, because of this code in libgcc/config/sol2-unwind.h: /* SIGFPE for IEEE-754 exceptions is delivered after the faulting insn rather than before it, so don't set fs->signal_frame in that case. We test whether the cexc field of the FSR is zero. */ if ((mctx->fpregs.fpu_fsr & 0x1f) == 0) fs->signal_frame = 1; If we unconditionally set fs->signal_frame, as is done on Linux, this would work. And it works on 64-bit SPARC, because those flags turn out to be zero. But on 32-bit SPARC, they are not zero. Specifically, bit 0 is set, indicating that an inexact operation occurred. I don't know why. That code was added by https://gcc.gnu.org/legacy-ml/gcc-patches/2013-05/msg01390.html. If I undo that change, so that fs->signal_frame is set unconditionally as it was before, then the Go test passes. I don't know why it is reasonable to assume that if the floating-point inexact flag is set then the signal is a floating-point signal. In this case that is clearly incorrect. Because the problem here appears to be a Solaris-specific problem with Solaris-specific code, I don't plan to work any further on it.