1
2
3
4
5
6
7
8
9 package debug_test
10
11 import (
12 "runtime"
13 "runtime/debug"
14 "syscall"
15 "testing"
16 "unsafe"
17 )
18
19 func TestPanicOnFault(t *testing.T) {
20 if runtime.GOARCH == "s390x" {
21 t.Skip("s390x fault addresses are missing the low order bits")
22 }
23 if runtime.GOOS == "ios" {
24 t.Skip("iOS doesn't provide fault addresses")
25 }
26 if runtime.GOOS == "netbsd" && runtime.GOARCH == "arm" {
27 t.Skip("netbsd-arm doesn't provide fault address (golang.org/issue/45026)")
28 }
29 m, err := syscall.Mmap(-1, 0, 0x1000, syscall.PROT_READ , syscall.MAP_SHARED|syscall.MAP_ANON)
30 if err != nil {
31 t.Fatalf("can't map anonymous memory: %s", err)
32 }
33 defer syscall.Munmap(m)
34 old := debug.SetPanicOnFault(true)
35 defer debug.SetPanicOnFault(old)
36 const lowBits = 0x3e7
37 defer func() {
38 r := recover()
39 if r == nil {
40 t.Fatalf("write did not fault")
41 }
42 type addressable interface {
43 Addr() uintptr
44 }
45 a, ok := r.(addressable)
46 if !ok {
47 t.Fatalf("fault does not contain address")
48 }
49 want := uintptr(unsafe.Pointer(&m[lowBits]))
50 got := a.Addr()
51 if got != want {
52 t.Fatalf("fault address %x, want %x", got, want)
53 }
54 }()
55 m[lowBits] = 1
56 }
57
View as plain text