diff --git a/src/runtime/crash_cgo_test.go b/src/runtime/crash_cgo_test.go index ad15ebf9c2..fb34c7fe3e 100644 --- a/src/runtime/crash_cgo_test.go +++ b/src/runtime/crash_cgo_test.go @@ -518,15 +518,21 @@ func TestCgoTracebackSigpanic(t *testing.T) { t.Parallel() got := runTestProg(t, "testprogcgo", "TracebackSigpanic") t.Log(got) - want := "runtime.sigpanic" + // We should see the function that calls the C function. + want := "main.TracebackSigpanic" if !strings.Contains(got, want) { if runtime.GOOS == "android" && (runtime.GOARCH == "arm" || runtime.GOARCH == "arm64") { testenv.SkipFlaky(t, 58794) } t.Errorf("did not see %q in output", want) } + // We shouldn't inject a sigpanic call. (see issue 57698) + nowant := "runtime.sigpanic" + if strings.Contains(got, nowant) { + t.Errorf("unexpectedly saw %q in output", nowant) + } // No runtime errors like "runtime: unexpected return pc". - nowant := "runtime: " + nowant = "runtime: " if strings.Contains(got, nowant) { t.Errorf("unexpectedly saw %q in output", nowant) } diff --git a/src/runtime/signal_unix.go b/src/runtime/signal_unix.go index 026a503eb1..d1719b22ff 100644 --- a/src/runtime/signal_unix.go +++ b/src/runtime/signal_unix.go @@ -673,9 +673,13 @@ func sighandler(sig uint32, info *siginfo, ctxt unsafe.Pointer, gp *g) { if sig < uint32(len(sigtable)) { flags = sigtable[sig].flags } - if !c.sigFromUser() && flags&_SigPanic != 0 && gp.throwsplit { + if !c.sigFromUser() && flags&_SigPanic != 0 && (gp.throwsplit || gp != mp.curg) { // We can't safely sigpanic because it may grow the // stack. Abort in the signal handler instead. + // + // Also don't inject a sigpanic if we are not on a + // user G stack. Either we're in the runtime, or we're + // running C code. Either way we cannot recover. flags = _SigThrow } if isAbortPC(c.sigpc()) {