aboutsummaryrefslogtreecommitdiff
path: root/src/runtime/signal_unix.go
diff options
context:
space:
mode:
authorKeith Randall <khr@golang.org>2020-02-28 12:59:38 -0800
committerKeith Randall <khr@golang.org>2020-03-02 18:46:06 +0000
commit63f1bc59922d454f288ad3d193bc60d7c980dbb0 (patch)
tree884810e5ed910ab100204f3b4f29e7c211438b18 /src/runtime/signal_unix.go
parenta2bff7c2964c6bf2c9741eb767d749d773f20770 (diff)
downloadgo-63f1bc59922d454f288ad3d193bc60d7c980dbb0.tar.gz
go-63f1bc59922d454f288ad3d193bc60d7c980dbb0.zip
runtime: print instruction bytes when reporting a SIGILL
Print the bytes of the instruction that generated a SIGILL. This should help us respond to bug reports without having to go back-and-forth with the reporter to get the instruction involved. Might also help with SIGILL problems that are difficult to reproduce. Update #37513 Change-Id: I33059b1dbfc97bce16142a843f32a88a6547e280 Reviewed-on: https://go-review.googlesource.com/c/go/+/221431 Run-TryBot: Keith Randall <khr@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Ian Lance Taylor <iant@golang.org>
Diffstat (limited to 'src/runtime/signal_unix.go')
-rw-r--r--src/runtime/signal_unix.go24
1 files changed, 24 insertions, 0 deletions
diff --git a/src/runtime/signal_unix.go b/src/runtime/signal_unix.go
index d2e6693805..32b192c977 100644
--- a/src/runtime/signal_unix.go
+++ b/src/runtime/signal_unix.go
@@ -607,6 +607,30 @@ func sighandler(sig uint32, info *siginfo, ctxt unsafe.Pointer, gp *g) {
print("signal arrived during cgo execution\n")
gp = _g_.m.lockedg.ptr()
}
+ if sig == _SIGILL {
+ // It would be nice to know how long the instruction is.
+ // Unfortunately, that's complicated to do in general (mostly for x86
+ // and s930x, but other archs have non-standard instruction lengths also).
+ // Opt to print 16 bytes, which covers most instructions.
+ const maxN = 16
+ n := uintptr(maxN)
+ // We have to be careful, though. If we're near the end of
+ // a page and the following page isn't mapped, we could
+ // segfault. So make sure we don't straddle a page (even though
+ // that could lead to printing an incomplete instruction).
+ // We're assuming here we can read at least the page containing the PC.
+ // I suppose it is possible that the page is mapped executable but not readable?
+ pc := c.sigpc()
+ if n > physPageSize-pc%physPageSize {
+ n = physPageSize - pc%physPageSize
+ }
+ print("instruction bytes:")
+ b := (*[maxN]byte)(unsafe.Pointer(pc))
+ for i := uintptr(0); i < n; i++ {
+ print(" ", hex(b[i]))
+ }
+ println()
+ }
print("\n")
level, _, docrash := gotraceback()