From 615d44c287a9c8a5f1062dd24ba341d806abc944 Mon Sep 17 00:00:00 2001 From: Austin Clements Date: Wed, 31 Jan 2018 17:34:22 -0500 Subject: runtime: refactor test for pushing sigpanic frame This logic is duplicated in all of the preparePanic functions. Pull it out into one architecture-independent function. Change-Id: I7ef4e78e3eda0b7be1a480fb5245fc7424fb2b4e Reviewed-on: https://go-review.googlesource.com/91255 Run-TryBot: Austin Clements TryBot-Result: Gobot Gobot Reviewed-by: Ian Lance Taylor --- src/runtime/panic.go | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) (limited to 'src/runtime/panic.go') diff --git a/src/runtime/panic.go b/src/runtime/panic.go index c51948bd18..e1477e2486 100644 --- a/src/runtime/panic.go +++ b/src/runtime/panic.go @@ -786,3 +786,36 @@ func canpanic(gp *g) bool { } return true } + +// shouldPushSigpanic returns true if pc should be used as sigpanic's +// return PC (pushing a frame for the call). Otherwise, it should be +// left alone so that LR is used as sigpanic's return PC, effectively +// replacing the top-most frame with sigpanic. This is used by +// preparePanic. +func shouldPushSigpanic(gp *g, pc, lr uintptr) bool { + if pc == 0 { + // Probably a call to a nil func. The old LR is more + // useful in the stack trace. Not pushing the frame + // will make the trace look like a call to sigpanic + // instead. (Otherwise the trace will end at sigpanic + // and we won't get to see who faulted.) + return false + } + // If we don't recognize the PC as code, but we do recognize + // 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() { + // This wasn't a bad call, so use PC as sigpanic's + // return PC. + return true + } + if findfunc(lr).valid() { + // This was a bad call, but the LR is good, so use the + // LR as sigpanic's return PC. + return false + } + // Neither the PC or LR is good. Hopefully pushing a frame + // will work. + return true +} -- cgit v1.3-5-g9baa