예제 #1
0
파일: probe.go 프로젝트: rdterner/debug
// write copies the argument buffer to memory starting at address p.
// Its boolean return tells whether it succeeded. If it fails, no bytes were copied.
func write(p uintptr, buf []byte) (ok bool) {
	defer catchFault(&ok)
	defer debug.SetPanicOnFault(debug.SetPanicOnFault(true))
	for i := range buf {
		*(*byte)(unsafe.Pointer(p)) = buf[i]
		p++
	}
	return true
}
예제 #2
0
func TestSetPanicOnFault(t *testing.T) {
	old := debug.SetPanicOnFault(true)
	defer debug.SetPanicOnFault(old)

	nfault := 0
	for _, addr := range faultAddrs {
		testSetPanicOnFault(t, uintptr(addr), &nfault)
	}
	if nfault == 0 {
		t.Fatalf("none of the addresses faulted")
	}
}
예제 #3
0
파일: probe.go 프로젝트: rdterner/debug
// validWrite reports whether a write of the specified size can be done at address p.
// TODO: It does this by actually doing a write and seeing if it succeeds. Do better.
func validWrite(p uintptr, size int) (ok bool) {
	// Check for negative size and for (p + size) overflow.
	if size < 0 || uint64(^uintptr(0)-p) < uint64(size) {
		return false
	}
	defer catchFault(&ok)
	defer debug.SetPanicOnFault(debug.SetPanicOnFault(true))
	ep := p + uintptr(size)
	for p < ep {
		*(*byte)(unsafe.Pointer(p)) = *(*byte)(unsafe.Pointer(p))
		p++
	}
	return true
}
예제 #4
0
func TestSetPanicOnFault(t *testing.T) {
	// This currently results in a fault in the signal trampoline on
	// dragonfly/386 - see issue 7421.
	if GOOS == "dragonfly" && GOARCH == "386" {
		t.Skip("skipping test on dragonfly/386")
	}

	old := debug.SetPanicOnFault(true)
	defer debug.SetPanicOnFault(old)

	for _, addr := range faultAddrs {
		testSetPanicOnFault(t, uintptr(addr))
	}
}
예제 #5
0
func TestSetPanicOnFault(t *testing.T) {
	old := debug.SetPanicOnFault(true)
	defer debug.SetPanicOnFault(old)

	defer func() {
		if err := recover(); err == nil {
			t.Fatalf("did not find error in recover")
		}
	}()

	var p *int
	p = (*int)(unsafe.Pointer(^uintptr(0)))
	println(*p)
	t.Fatalf("still here - should have faulted")
}
예제 #6
0
func main() {
	// Turn the eventual fault into a panic, not a program crash,
	// so that memcopy can recover.
	debug.SetPanicOnFault(true)

	size := syscall.Getpagesize()

	// Map 16 pages of data with a 4-page hole in the middle.
	data, err := syscall.Mmap(-1, 0, 16*size, syscall.PROT_READ|syscall.PROT_WRITE, syscall.MAP_ANON|syscall.MAP_PRIVATE)
	if err != nil {
		log.Fatalf("mmap: %v", err)
	}

	// Note: Cannot call syscall.Munmap, because Munmap checks
	// that you are unmapping a whole region returned by Mmap.
	// We are trying to unmap just a hole in the middle.
	if _, _, err := syscall.Syscall(syscall.SYS_MUNMAP, uintptr(unsafe.Pointer(&data[8*size])), uintptr(4*size), 0); err != 0 {
		log.Fatalf("munmap: %v", err)
	}

	other := make([]byte, 16*size)

	// Check that memcopy returns the actual amount copied
	// before the fault (8*size - 5, the offset we skip in the argument).
	n, err := memcopy(data[5:], other)
	if err == nil {
		log.Fatal("no error from memcopy across memory hole")
	}
	if n != 8*size-5 {
		log.Fatal("memcopy returned %d, want %d", n, 8*size-5)
	}
}
예제 #7
0
func TestSetPanicOnFault(t *testing.T) {
	// This currently results in a fault in the signal trampoline on
	// dragonfly/386 - see issue 7421.
	if GOOS == "dragonfly" && GOARCH == "386" {
		t.Skip("skipping test on dragonfly/386")
	}

	old := debug.SetPanicOnFault(true)
	defer debug.SetPanicOnFault(old)

	for _, addr := range faultAddrs {
		if Compiler == "gccgo" && GOARCH == "386" && (addr&0xff000000) != 0 {
			// On gccgo these addresses can be used for
			// the thread stack.
			continue
		}
		testSetPanicOnFault(t, uintptr(addr))
	}
}
예제 #8
0
func TestSetPanicOnFault(t *testing.T) {
	t.Skip("skipping for llgo due to lack of non-call exception support")

	// This currently results in a fault in the signal trampoline on
	// dragonfly/386 - see issue 7421.
	if GOOS == "dragonfly" && GOARCH == "386" {
		t.Skip("skipping test on dragonfly/386")
	}

	old := debug.SetPanicOnFault(true)
	defer debug.SetPanicOnFault(old)

	nfault := 0
	for _, addr := range faultAddrs {
		testSetPanicOnFault(t, uintptr(addr), &nfault)
	}
	if nfault == 0 {
		t.Fatalf("none of the addresses faulted")
	}
}
예제 #9
0
func TestSetPanicOnFault(t *testing.T) {
	// This currently results in a fault in the signal trampoline on
	// dragonfly/386 - see issue 7421.
	if GOOS == "dragonfly" && GOARCH == "386" {
		t.Skip("skipping test on dragonfly/386")
	}

	old := debug.SetPanicOnFault(true)
	defer debug.SetPanicOnFault(old)

	defer func() {
		if err := recover(); err == nil {
			t.Fatalf("did not find error in recover")
		}
	}()

	var p *int
	p = (*int)(unsafe.Pointer(^uintptr(0)))
	println(*p)
	t.Fatalf("still here - should have faulted")
}
예제 #10
0
파일: issue11656.go 프로젝트: wycharry/go
func main() {
	debug.SetPanicOnFault(true)
	defer func() {
		if err := recover(); err == nil {
			panic("not panicking")
		}
		pc, _, _, _ := runtime.Caller(10)
		f := runtime.FuncForPC(pc)
		if f == nil || f.Name() != "main.f" {
			if f == nil {
				println("no func for ", unsafe.Pointer(pc))
			} else {
				println("found func:", f.Name())
			}
			panic("cannot find main.f on stack")
		}
	}()
	f(20)
}