Rebase.
[official-gcc.git] / libgo / go / runtime / runtime_test.go
blob5c504675968cc969fcf2dfdd239e44431898b378
1 // Copyright 2012 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.
5 package runtime_test
7 import (
8 "io"
9 // "io/ioutil"
10 // "os"
11 // "os/exec"
12 . "runtime"
13 "runtime/debug"
14 // "strconv"
15 // "strings"
16 "testing"
17 "unsafe"
20 var errf error
22 func errfn() error {
23 return errf
26 func errfn1() error {
27 return io.EOF
30 func BenchmarkIfaceCmp100(b *testing.B) {
31 for i := 0; i < b.N; i++ {
32 for j := 0; j < 100; j++ {
33 if errfn() == io.EOF {
34 b.Fatal("bad comparison")
40 func BenchmarkIfaceCmpNil100(b *testing.B) {
41 for i := 0; i < b.N; i++ {
42 for j := 0; j < 100; j++ {
43 if errfn1() == nil {
44 b.Fatal("bad comparison")
50 func BenchmarkDefer(b *testing.B) {
51 for i := 0; i < b.N; i++ {
52 defer1()
56 func defer1() {
57 defer func(x, y, z int) {
58 if recover() != nil || x != 1 || y != 2 || z != 3 {
59 panic("bad recover")
61 }(1, 2, 3)
62 return
65 func BenchmarkDefer10(b *testing.B) {
66 for i := 0; i < b.N/10; i++ {
67 defer2()
71 func defer2() {
72 for i := 0; i < 10; i++ {
73 defer func(x, y, z int) {
74 if recover() != nil || x != 1 || y != 2 || z != 3 {
75 panic("bad recover")
77 }(1, 2, 3)
81 func BenchmarkDeferMany(b *testing.B) {
82 for i := 0; i < b.N; i++ {
83 defer func(x, y, z int) {
84 if recover() != nil || x != 1 || y != 2 || z != 3 {
85 panic("bad recover")
87 }(1, 2, 3)
91 /* The go tool is not present in gccgo.
93 // The profiling signal handler needs to know whether it is executing runtime.gogo.
94 // The constant RuntimeGogoBytes in arch_*.h gives the size of the function;
95 // we don't have a way to obtain it from the linker (perhaps someday).
96 // Test that the constant matches the size determined by 'go tool nm -S'.
97 // The value reported will include the padding between runtime.gogo and the
98 // next function in memory. That's fine.
99 func TestRuntimeGogoBytes(t *testing.T) {
100 if GOOS == "nacl" {
101 t.Skip("skipping on nacl")
104 dir, err := ioutil.TempDir("", "go-build")
105 if err != nil {
106 t.Fatalf("failed to create temp directory: %v", err)
108 defer os.RemoveAll(dir)
110 out, err := exec.Command("go", "build", "-o", dir+"/hello", "../../../test/helloworld.go").CombinedOutput()
111 if err != nil {
112 t.Fatalf("building hello world: %v\n%s", err, out)
115 out, err = exec.Command("go", "tool", "nm", "-size", dir+"/hello").CombinedOutput()
116 if err != nil {
117 t.Fatalf("go tool nm: %v\n%s", err, out)
120 for _, line := range strings.Split(string(out), "\n") {
121 f := strings.Fields(line)
122 if len(f) == 4 && f[3] == "runtime.gogo" {
123 size, _ := strconv.Atoi(f[1])
124 if GogoBytes() != int32(size) {
125 t.Fatalf("RuntimeGogoBytes = %d, should be %d", GogoBytes(), size)
127 return
131 t.Fatalf("go tool nm did not report size for runtime.gogo")
135 // golang.org/issue/7063
136 func TestStopCPUProfilingWithProfilerOff(t *testing.T) {
137 SetCPUProfileRate(0)
140 // Addresses to test for faulting behavior.
141 // This is less a test of SetPanicOnFault and more a check that
142 // the operating system and the runtime can process these faults
143 // correctly. That is, we're indirectly testing that without SetPanicOnFault
144 // these would manage to turn into ordinary crashes.
145 // Note that these are truncated on 32-bit systems, so the bottom 32 bits
146 // of the larger addresses must themselves be invalid addresses.
147 // We might get unlucky and the OS might have mapped one of these
148 // addresses, but probably not: they're all in the first page, very high
149 // adderesses that normally an OS would reserve for itself, or malformed
150 // addresses. Even so, we might have to remove one or two on different
151 // systems. We will see.
153 var faultAddrs = []uint64{
154 // low addresses
157 0xfff,
158 // high (kernel) addresses
159 // or else malformed.
160 0xffffffffffffffff,
161 0xfffffffffffff001,
162 // no 0xffffffffffff0001; 0xffff0001 is mapped for 32-bit user space on OS X
163 // no 0xfffffffffff00001; 0xfff00001 is mapped for 32-bit user space sometimes on Linux
164 0xffffffffff000001,
165 0xfffffffff0000001,
166 0xffffffff00000001,
167 0xfffffff000000001,
168 0xffffff0000000001,
169 0xfffff00000000001,
170 0xffff000000000001,
171 0xfff0000000000001,
172 0xff00000000000001,
173 0xf000000000000001,
174 0x8000000000000001,
177 func TestSetPanicOnFault(t *testing.T) {
178 // This currently results in a fault in the signal trampoline on
179 // dragonfly/386 - see issue 7421.
180 if GOOS == "dragonfly" && GOARCH == "386" {
181 t.Skip("skipping test on dragonfly/386")
184 old := debug.SetPanicOnFault(true)
185 defer debug.SetPanicOnFault(old)
187 for _, addr := range faultAddrs {
188 if Compiler == "gccgo" && GOARCH == "386" && (addr&0xff000000) != 0 {
189 // On gccgo these addresses can be used for
190 // the thread stack.
191 continue
193 testSetPanicOnFault(t, uintptr(addr))
197 func testSetPanicOnFault(t *testing.T, addr uintptr) {
198 if GOOS == "nacl" {
199 t.Skip("nacl doesn't seem to fault on high addresses")
202 defer func() {
203 if err := recover(); err == nil {
204 t.Fatalf("did not find error in recover")
208 var p *int
209 p = (*int)(unsafe.Pointer(addr))
210 println(*p)
211 t.Fatalf("still here - should have faulted on address %#x", addr)