diff options
author | Keith Randall <khr@golang.org> | 2020-02-28 12:59:38 -0800 |
---|---|---|
committer | Keith Randall <khr@golang.org> | 2020-03-02 18:46:06 +0000 |
commit | 63f1bc59922d454f288ad3d193bc60d7c980dbb0 (patch) | |
tree | 884810e5ed910ab100204f3b4f29e7c211438b18 /src/runtime/signal_unix.go | |
parent | a2bff7c2964c6bf2c9741eb767d749d773f20770 (diff) | |
download | go-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.go | 24 |
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() |