diff options
| author | Austin Clements <austin@google.com> | 2018-01-31 17:34:22 -0500 |
|---|---|---|
| committer | Austin Clements <austin@google.com> | 2018-02-13 21:01:25 +0000 |
| commit | 615d44c287a9c8a5f1062dd24ba341d806abc944 (patch) | |
| tree | 23cb45d41b62fcd1c539ae067b33aadb05606031 /src/runtime/panic.go | |
| parent | b1679e4d03268a6792e6b8d573ac31080d9d9baf (diff) | |
| download | go-615d44c287a9c8a5f1062dd24ba341d806abc944.tar.xz | |
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 <austin@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
Diffstat (limited to 'src/runtime/panic.go')
| -rw-r--r-- | src/runtime/panic.go | 33 |
1 files changed, 33 insertions, 0 deletions
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 +} |
