github.com/twelsh-aw/go/src@v0.0.0-20230516233729-a56fe86a7c81/runtime/debug/panic_test.go (about) 1 // Copyright 2020 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 //go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd 6 7 // TODO: test on Windows? 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 /* Note: no PROT_WRITE */, 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 // will fault 56 }