diff --git a/src/runtime/panic.go b/src/runtime/panic.go index e1477e2486..55ecb67654 100644 --- a/src/runtime/panic.go +++ b/src/runtime/panic.go @@ -805,7 +805,12 @@ func shouldPushSigpanic(gp *g, pc, lr uintptr) bool { // the link register as code, then this assumes the panic was // caused by a call to non-code. In this case, we want to // ignore this call to make unwinding show the context. - if findfunc(pc).valid() { + // + // If we running C code, we're not going to recognize pc as a + // Go function, so just assume it's good. Otherwise, traceback + // may try to read a stale LR that looks like a Go code + // pointer and wander into the woods. + if gp.m.incgo || findfunc(pc).valid() { // This wasn't a bad call, so use PC as sigpanic's // return PC. return true diff --git a/src/runtime/traceback.go b/src/runtime/traceback.go index 747176c278..2261942ab4 100644 --- a/src/runtime/traceback.go +++ b/src/runtime/traceback.go @@ -287,7 +287,7 @@ func gentraceback(pc0, sp0, lr0 uintptr, gp *g, skip int, pcbuf *uintptr, max in // But if callback is set, we're doing a garbage collection and must // get everything, so crash loudly. doPrint := printing - if doPrint && gp.m.incgo { + if doPrint && gp.m.incgo && f.entry == sigpanicPC { // We can inject sigpanic // calls directly into C code, // in which case we'll see a C