summaryrefslogtreecommitdiff
path: root/libgo/go/runtime/runtime_test.go
diff options
context:
space:
mode:
Diffstat (limited to 'libgo/go/runtime/runtime_test.go')
-rw-r--r--libgo/go/runtime/runtime_test.go131
1 files changed, 128 insertions, 3 deletions
diff --git a/libgo/go/runtime/runtime_test.go b/libgo/go/runtime/runtime_test.go
index d121929561..8059d1ad9a 100644
--- a/libgo/go/runtime/runtime_test.go
+++ b/libgo/go/runtime/runtime_test.go
@@ -9,10 +9,12 @@ import (
// "io/ioutil"
// "os"
// "os/exec"
- // . "runtime"
+ . "runtime"
+ "runtime/debug"
// "strconv"
// "strings"
"testing"
+ "unsafe"
)
var errf error
@@ -95,18 +97,23 @@ 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) {
+ switch GOOS {
+ case "android", "nacl":
+ t.Skipf("skipping on %s", GOOS)
+ }
+
dir, err := ioutil.TempDir("", "go-build")
if err != nil {
t.Fatalf("failed to create temp directory: %v", err)
}
defer os.RemoveAll(dir)
- out, err := exec.Command("go", "build", "-o", dir+"/hello", "../../../test/helloworld.go").CombinedOutput()
+ out, err := exec.Command("go", "build", "-o", dir+"/hello", "../../test/helloworld.go").CombinedOutput()
if err != nil {
t.Fatalf("building hello world: %v\n%s", err, out)
}
- out, err = exec.Command("go", "tool", "nm", "-S", dir+"/hello").CombinedOutput()
+ out, err = exec.Command("go", "tool", "nm", "-size", dir+"/hello").CombinedOutput()
if err != nil {
t.Fatalf("go tool nm: %v\n%s", err, out)
}
@@ -125,3 +132,121 @@ func TestRuntimeGogoBytes(t *testing.T) {
t.Fatalf("go tool nm did not report size for runtime.gogo")
}
*/
+
+// golang.org/issue/7063
+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,
+ 0xffffffffffff0001,
+ 0xfffffffffff00001,
+ 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)
+
+ nfault := 0
+ for _, addr := range faultAddrs {
+ testSetPanicOnFault(t, uintptr(addr), &nfault)
+ }
+ if nfault == 0 {
+ t.Fatalf("none of the addresses faulted")
+ }
+}
+
+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 {
+ *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.
+ v := *(*byte)(unsafe.Pointer(addr))
+ t.Logf("addr %#x: %#x\n", addr, v)
+}
+
+func eqstring_generic(s1, s2 string) bool {
+ if len(s1) != len(s2) {
+ return false
+ }
+ // optimization in assembly versions:
+ // if s1.str == s2.str { return true }
+ for i := 0; i < len(s1); i++ {
+ if s1[i] != s2[i] {
+ return false
+ }
+ }
+ return true
+}
+
+func TestEqString(t *testing.T) {
+ // This isn't really an exhaustive test of eqstring, it's
+ // just a convenient way of documenting (via eqstring_generic)
+ // what eqstring does.
+ s := []string{
+ "",
+ "a",
+ "c",
+ "aaa",
+ "ccc",
+ "cccc"[:3], // same contents, different string
+ "1234567890",
+ }
+ for _, s1 := range s {
+ for _, s2 := range s {
+ x := s1 == s2
+ y := eqstring_generic(s1, s2)
+ if x != y {
+ t.Errorf(`eqstring("%s","%s") = %t, want %t`, s1, s2, x, y)
+ }
+ }
+ }
+}