From 5fdea3430aed2224a88efa764034ef2ee2b4ccb1 Mon Sep 17 00:00:00 2001 From: Russ Cox Date: Thu, 18 Sep 2014 21:43:09 -0400 Subject: runtime: revise TestSetPanicOnFault We can't assume all those addresses are unmapped. But at least one should be. What we're really testing is that the program doesn't crash. Fixes #8542. LGTM=iant R=golang-codereviews, iant, minux CC=golang-codereviews https://golang.org/cl/144120043 --- src/runtime/runtime_test.go | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) (limited to 'src/runtime/runtime_test.go') diff --git a/src/runtime/runtime_test.go b/src/runtime/runtime_test.go index cffc9f7d35..3c4075842b 100644 --- a/src/runtime/runtime_test.go +++ b/src/runtime/runtime_test.go @@ -157,8 +157,8 @@ var faultAddrs = []uint64{ // or else malformed. 0xffffffffffffffff, 0xfffffffffffff001, - // no 0xffffffffffff0001; 0xffff0001 is mapped for 32-bit user space on OS X - // no 0xfffffffffff00001; 0xfff00001 is mapped for 32-bit user space sometimes on Linux + 0xffffffffffff0001, + 0xfffffffffff00001, 0xffffffffff000001, 0xfffffffff0000001, 0xffffffff00000001, @@ -182,26 +182,33 @@ func TestSetPanicOnFault(t *testing.T) { old := debug.SetPanicOnFault(true) defer debug.SetPanicOnFault(old) + nfault := 0 for _, addr := range faultAddrs { - testSetPanicOnFault(t, uintptr(addr)) + testSetPanicOnFault(t, uintptr(addr), &nfault) + } + if nfault == 0 { + t.Fatalf("none of the addresses faulted") } } -func testSetPanicOnFault(t *testing.T, addr uintptr) { +func testSetPanicOnFault(t *testing.T, addr uintptr, nfault *int) { if GOOS == "nacl" { t.Skip("nacl doesn't seem to fault on high addresses") } defer func() { - if err := recover(); err == nil { - t.Fatalf("did not find error in recover") + if err := recover(); err != nil { + *nfault++ } }() + // The read should fault, except that sometimes we hit + // addresses that have had C or kernel pages mapped there + // readable by user code. So just log the content. + // If no addresses fault, we'll fail the test. var p *int p = (*int)(unsafe.Pointer(addr)) - println(*p) - t.Fatalf("still here - should have faulted on address %#x", addr) + t.Logf("addr %#x: %#x\n", addr, *p) } func eqstring_generic(s1, s2 string) bool { -- cgit v1.3 From 3b2577ced39194fdd2f1359136c7e176d8de5576 Mon Sep 17 00:00:00 2001 From: Keith Randall Date: Sat, 20 Sep 2014 23:31:11 -0700 Subject: runtime: be very careful with bad pointer tests Saw this on a test: runtime: bad pointer in frame runtime_test.testSetPanicOnFault at 0xc20801c6b0: 0xfff fatal error: bad pointer! runtime stack: ... copystack(0xc2081bf7a0, 0x1000) /root/work/solaris-amd64-smartos-2dde8b453d26/go/src/runtime/stack.c:621 +0x173 fp=0xfffffd7ffd5ffee0 sp=0xfffffd7ffd5ffe20 runtime.newstack() /root/work/solaris-amd64-smartos-2dde8b453d26/go/src/runtime/stack.c:774 +0x552 fp=0xfffffd7ffd5fff90 sp=0xfffffd7ffd5ffee0 runtime.morestack() /root/work/solaris-amd64-smartos-2dde8b453d26/go/src/runtime/asm_amd64.s:324 +0x90 fp=0xfffffd7ffd5fff98 sp=0xfffffd7ffd5fff90 goroutine 163354 [stack growth]: ... runtime.convT2E(0x587000, 0xc20807bea8, 0x0, 0x0) /root/work/solaris-amd64-smartos-2dde8b453d26/go/src/runtime/iface.go:141 +0xd2 fp=0xc20801c678 sp=0xc20801c640 runtime_test.testSetPanicOnFault(0xc20822c510, 0xfff, 0xc20801c748) /root/work/solaris-amd64-smartos-2dde8b453d26/go/src/runtime/runtime_test.go:211 +0xc6 fp=0xc20801c718 sp=0xc20801c678 ... This test is testing bad pointers. It loads the bad pointer into a pointer variable, but before it gets a chance to dereference it, calls convT2E. That call causes a stack copy, which exposes that live but bad pointer variable. LGTM=dvyukov R=golang-codereviews, dvyukov CC=golang-codereviews https://golang.org/cl/146880043 --- src/runtime/runtime_test.go | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'src/runtime/runtime_test.go') diff --git a/src/runtime/runtime_test.go b/src/runtime/runtime_test.go index 3c4075842b..1688364a8e 100644 --- a/src/runtime/runtime_test.go +++ b/src/runtime/runtime_test.go @@ -206,9 +206,8 @@ func testSetPanicOnFault(t *testing.T, addr uintptr, nfault *int) { // addresses that have had C or kernel pages mapped there // readable by user code. So just log the content. // If no addresses fault, we'll fail the test. - var p *int - p = (*int)(unsafe.Pointer(addr)) - t.Logf("addr %#x: %#x\n", addr, *p) + v := *(*byte)(unsafe.Pointer(addr)) + t.Logf("addr %#x: %#x\n", addr, v) } func eqstring_generic(s1, s2 string) bool { -- cgit v1.3