diff options
Diffstat (limited to 'libgo/go/runtime/runtime_test.go')
-rw-r--r-- | libgo/go/runtime/runtime_test.go | 82 |
1 files changed, 79 insertions, 3 deletions
diff --git a/libgo/go/runtime/runtime_test.go b/libgo/go/runtime/runtime_test.go index 1702298aed1..7dae95a2d4f 100644 --- a/libgo/go/runtime/runtime_test.go +++ b/libgo/go/runtime/runtime_test.go @@ -10,9 +10,11 @@ import ( // "os" // "os/exec" // . "runtime" + "runtime/debug" // "strconv" // "strings" "testing" + "unsafe" ) var errf error @@ -95,10 +97,10 @@ func BenchmarkDeferMany(b *testing.B) { // The value reported will include the padding between runtime.gogo and the // next function in memory. That's fine. func TestRuntimeGogoBytes(t *testing.T) { - // TODO(brainman): delete when issue 6973 is fixed. - if GOOS == "windows" { - t.Skip("skipping broken test on windows") + if GOOS == "nacl" { + t.Skip("skipping on nacl") } + dir, err := ioutil.TempDir("", "go-build") if err != nil { t.Fatalf("failed to create temp directory: %v", err) @@ -134,3 +136,77 @@ func TestRuntimeGogoBytes(t *testing.T) { func TestStopCPUProfilingWithProfilerOff(t *testing.T) { SetCPUProfileRate(0) } + +// Addresses to test for faulting behavior. +// This is less a test of SetPanicOnFault and more a check that +// the operating system and the runtime can process these faults +// correctly. That is, we're indirectly testing that without SetPanicOnFault +// these would manage to turn into ordinary crashes. +// Note that these are truncated on 32-bit systems, so the bottom 32 bits +// of the larger addresses must themselves be invalid addresses. +// We might get unlucky and the OS might have mapped one of these +// addresses, but probably not: they're all in the first page, very high +// adderesses that normally an OS would reserve for itself, or malformed +// addresses. Even so, we might have to remove one or two on different +// systems. We will see. + +var faultAddrs = []uint64{ + // low addresses + 0, + 1, + 0xfff, + // high (kernel) addresses + // 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 + 0xffffffffff000001, + 0xfffffffff0000001, + 0xffffffff00000001, + 0xfffffff000000001, + 0xffffff0000000001, + 0xfffff00000000001, + 0xffff000000000001, + 0xfff0000000000001, + 0xff00000000000001, + 0xf000000000000001, + 0x8000000000000001, +} + +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)) + } +} + +func testSetPanicOnFault(t *testing.T, addr uintptr) { + 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") + } + }() + + var p *int + p = (*int)(unsafe.Pointer(addr)) + println(*p) + t.Fatalf("still here - should have faulted on address %#x", addr) +} |