runtime: scan register backing store on ia64
[official-gcc.git] / libgo / go / runtime / runtime_test.go
blob0231043260bbaf1e2b10455abf93155c797f5ba1
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 "flag"
9 "io"
10 . "runtime"
11 "runtime/debug"
12 "strings"
13 "testing"
14 "unsafe"
17 var flagQuick = flag.Bool("quick", false, "skip slow tests, for second run in all.bash")
19 func init() {
20 // We're testing the runtime, so make tracebacks show things
21 // in the runtime. This only raises the level, so it won't
22 // override GOTRACEBACK=crash from the user.
23 SetTracebackEnv("system")
26 var errf error
28 func errfn() error {
29 return errf
32 func errfn1() error {
33 return io.EOF
36 func BenchmarkIfaceCmp100(b *testing.B) {
37 for i := 0; i < b.N; i++ {
38 for j := 0; j < 100; j++ {
39 if errfn() == io.EOF {
40 b.Fatal("bad comparison")
46 func BenchmarkIfaceCmpNil100(b *testing.B) {
47 for i := 0; i < b.N; i++ {
48 for j := 0; j < 100; j++ {
49 if errfn1() == nil {
50 b.Fatal("bad comparison")
56 var efaceCmp1 interface{}
57 var efaceCmp2 interface{}
59 func BenchmarkEfaceCmpDiff(b *testing.B) {
60 x := 5
61 efaceCmp1 = &x
62 y := 6
63 efaceCmp2 = &y
64 for i := 0; i < b.N; i++ {
65 for j := 0; j < 100; j++ {
66 if efaceCmp1 == efaceCmp2 {
67 b.Fatal("bad comparison")
73 func BenchmarkDefer(b *testing.B) {
74 for i := 0; i < b.N; i++ {
75 defer1()
79 func defer1() {
80 defer func(x, y, z int) {
81 if recover() != nil || x != 1 || y != 2 || z != 3 {
82 panic("bad recover")
84 }(1, 2, 3)
87 func BenchmarkDefer10(b *testing.B) {
88 for i := 0; i < b.N/10; i++ {
89 defer2()
93 func defer2() {
94 for i := 0; i < 10; i++ {
95 defer func(x, y, z int) {
96 if recover() != nil || x != 1 || y != 2 || z != 3 {
97 panic("bad recover")
99 }(1, 2, 3)
103 func BenchmarkDeferMany(b *testing.B) {
104 for i := 0; i < b.N; i++ {
105 defer func(x, y, z int) {
106 if recover() != nil || x != 1 || y != 2 || z != 3 {
107 panic("bad recover")
109 }(1, 2, 3)
113 // golang.org/issue/7063
114 func TestStopCPUProfilingWithProfilerOff(t *testing.T) {
115 SetCPUProfileRate(0)
118 // Addresses to test for faulting behavior.
119 // This is less a test of SetPanicOnFault and more a check that
120 // the operating system and the runtime can process these faults
121 // correctly. That is, we're indirectly testing that without SetPanicOnFault
122 // these would manage to turn into ordinary crashes.
123 // Note that these are truncated on 32-bit systems, so the bottom 32 bits
124 // of the larger addresses must themselves be invalid addresses.
125 // We might get unlucky and the OS might have mapped one of these
126 // addresses, but probably not: they're all in the first page, very high
127 // addresses that normally an OS would reserve for itself, or malformed
128 // addresses. Even so, we might have to remove one or two on different
129 // systems. We will see.
131 var faultAddrs = []uint64{
132 // low addresses
135 0xfff,
136 // high (kernel) addresses
137 // or else malformed.
138 0xffffffffffffffff,
139 0xfffffffffffff001,
140 0xffffffffffff0001,
141 0xfffffffffff00001,
142 0xffffffffff000001,
143 0xfffffffff0000001,
144 0xffffffff00000001,
145 0xfffffff000000001,
146 0xffffff0000000001,
147 0xfffff00000000001,
148 0xffff000000000001,
149 0xfff0000000000001,
150 0xff00000000000001,
151 0xf000000000000001,
152 0x8000000000000001,
155 func TestSetPanicOnFault(t *testing.T) {
156 old := debug.SetPanicOnFault(true)
157 defer debug.SetPanicOnFault(old)
159 nfault := 0
160 for _, addr := range faultAddrs {
161 testSetPanicOnFault(t, uintptr(addr), &nfault)
163 if nfault == 0 {
164 t.Fatalf("none of the addresses faulted")
168 func testSetPanicOnFault(t *testing.T, addr uintptr, nfault *int) {
169 if GOOS == "nacl" {
170 t.Skip("nacl doesn't seem to fault on high addresses")
173 defer func() {
174 if err := recover(); err != nil {
175 *nfault++
179 // The read should fault, except that sometimes we hit
180 // addresses that have had C or kernel pages mapped there
181 // readable by user code. So just log the content.
182 // If no addresses fault, we'll fail the test.
183 v := *(*byte)(unsafe.Pointer(addr))
184 t.Logf("addr %#x: %#x\n", addr, v)
187 func eqstring_generic(s1, s2 string) bool {
188 if len(s1) != len(s2) {
189 return false
191 // optimization in assembly versions:
192 // if s1.str == s2.str { return true }
193 for i := 0; i < len(s1); i++ {
194 if s1[i] != s2[i] {
195 return false
198 return true
201 func TestEqString(t *testing.T) {
202 // This isn't really an exhaustive test of == on strings, it's
203 // just a convenient way of documenting (via eqstring_generic)
204 // what == does.
205 s := []string{
207 "a",
208 "c",
209 "aaa",
210 "ccc",
211 "cccc"[:3], // same contents, different string
212 "1234567890",
214 for _, s1 := range s {
215 for _, s2 := range s {
216 x := s1 == s2
217 y := eqstring_generic(s1, s2)
218 if x != y {
219 t.Errorf(`("%s" == "%s") = %t, want %t`, s1, s2, x, y)
226 func TestTrailingZero(t *testing.T) {
227 // make sure we add padding for structs with trailing zero-sized fields
228 type T1 struct {
229 n int32
230 z [0]byte
232 if unsafe.Sizeof(T1{}) != 8 {
233 t.Errorf("sizeof(%#v)==%d, want 8", T1{}, unsafe.Sizeof(T1{}))
235 type T2 struct {
236 n int64
237 z struct{}
239 if unsafe.Sizeof(T2{}) != 8+unsafe.Sizeof(Uintreg(0)) {
240 t.Errorf("sizeof(%#v)==%d, want %d", T2{}, unsafe.Sizeof(T2{}), 8+unsafe.Sizeof(Uintreg(0)))
242 type T3 struct {
243 n byte
244 z [4]struct{}
246 if unsafe.Sizeof(T3{}) != 2 {
247 t.Errorf("sizeof(%#v)==%d, want 2", T3{}, unsafe.Sizeof(T3{}))
249 // make sure padding can double for both zerosize and alignment
250 type T4 struct {
251 a int32
252 b int16
253 c int8
254 z struct{}
256 if unsafe.Sizeof(T4{}) != 8 {
257 t.Errorf("sizeof(%#v)==%d, want 8", T4{}, unsafe.Sizeof(T4{}))
259 // make sure we don't pad a zero-sized thing
260 type T5 struct {
262 if unsafe.Sizeof(T5{}) != 0 {
263 t.Errorf("sizeof(%#v)==%d, want 0", T5{}, unsafe.Sizeof(T5{}))
268 func TestBadOpen(t *testing.T) {
269 if GOOS == "windows" || GOOS == "nacl" {
270 t.Skip("skipping OS that doesn't have open/read/write/close")
272 // make sure we get the correct error code if open fails. Same for
273 // read/write/close on the resulting -1 fd. See issue 10052.
274 nonfile := []byte("/notreallyafile")
275 fd := Open(&nonfile[0], 0, 0)
276 if fd != -1 {
277 t.Errorf("open(\"%s\")=%d, want -1", string(nonfile), fd)
279 var buf [32]byte
280 r := Read(-1, unsafe.Pointer(&buf[0]), int32(len(buf)))
281 if r != -1 {
282 t.Errorf("read()=%d, want -1", r)
284 w := Write(^uintptr(0), unsafe.Pointer(&buf[0]), int32(len(buf)))
285 if w != -1 {
286 t.Errorf("write()=%d, want -1", w)
288 c := Close(-1)
289 if c != -1 {
290 t.Errorf("close()=%d, want -1", c)
294 func TestAppendGrowth(t *testing.T) {
295 var x []int64
296 check := func(want int) {
297 if cap(x) != want {
298 t.Errorf("len=%d, cap=%d, want cap=%d", len(x), cap(x), want)
302 check(0)
303 want := 1
304 for i := 1; i <= 100; i++ {
305 x = append(x, 1)
306 check(want)
307 if i&(i-1) == 0 {
308 want = 2 * i
313 var One = []int64{1}
315 func TestAppendSliceGrowth(t *testing.T) {
316 var x []int64
317 check := func(want int) {
318 if cap(x) != want {
319 t.Errorf("len=%d, cap=%d, want cap=%d", len(x), cap(x), want)
323 check(0)
324 want := 1
325 for i := 1; i <= 100; i++ {
326 x = append(x, One...)
327 check(want)
328 if i&(i-1) == 0 {
329 want = 2 * i
334 func TestGoroutineProfileTrivial(t *testing.T) {
335 // Calling GoroutineProfile twice in a row should find the same number of goroutines,
336 // but it's possible there are goroutines just about to exit, so we might end up
337 // with fewer in the second call. Try a few times; it should converge once those
338 // zombies are gone.
339 for i := 0; ; i++ {
340 n1, ok := GoroutineProfile(nil) // should fail, there's at least 1 goroutine
341 if n1 < 1 || ok {
342 t.Fatalf("GoroutineProfile(nil) = %d, %v, want >0, false", n1, ok)
344 n2, ok := GoroutineProfile(make([]StackRecord, n1))
345 if n2 == n1 && ok {
346 break
348 t.Logf("GoroutineProfile(%d) = %d, %v, want %d, true", n1, n2, ok, n1)
349 if i >= 10 {
350 t.Fatalf("GoroutineProfile not converging")
355 func TestVersion(t *testing.T) {
356 // Test that version does not contain \r or \n.
357 vers := Version()
358 if strings.Contains(vers, "\r") || strings.Contains(vers, "\n") {
359 t.Fatalf("cr/nl in version: %q", vers)