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