blob: b62febd48ddc28b77fa37f6bfb2beca2a42141bb [file] [log] [blame]
Russ Cox57eb06f2012-02-16 23:51:04 -05001// run
Russ Cox6ee6d6e2009-01-28 16:58:48 -08002
3// Copyright 2009 The Go Authors. All rights reserved.
4// Use of this source code is governed by a BSD-style
5// license that can be found in the LICENSE file.
6
Rob Pike80a97832012-02-24 11:48:19 +11007// Test stack splitting code.
Russ Cox6ee6d6e2009-01-28 16:58:48 -08008// Try to tickle stack splitting bugs by doing
Russ Cox0f4f2a62009-02-06 13:46:56 -08009// go, defer, and closure calls at different stack depths.
Russ Cox6ee6d6e2009-01-28 16:58:48 -080010
11package main
12
Rob Pike325cf8e2010-03-24 16:46:53 -070013type T [20]int
Russ Cox6ee6d6e2009-01-28 16:58:48 -080014
15func g(c chan int, t T) {
Rob Pike325cf8e2010-03-24 16:46:53 -070016 s := 0
Russ Cox6ee6d6e2009-01-28 16:58:48 -080017 for i := 0; i < len(t); i++ {
Rob Pike325cf8e2010-03-24 16:46:53 -070018 s += t[i]
Russ Cox6ee6d6e2009-01-28 16:58:48 -080019 }
Rob Pike325cf8e2010-03-24 16:46:53 -070020 c <- s
Russ Cox6ee6d6e2009-01-28 16:58:48 -080021}
22
23func d(t T) {
Rob Pike325cf8e2010-03-24 16:46:53 -070024 s := 0
Russ Cox6ee6d6e2009-01-28 16:58:48 -080025 for i := 0; i < len(t); i++ {
Rob Pike325cf8e2010-03-24 16:46:53 -070026 s += t[i]
Russ Cox6ee6d6e2009-01-28 16:58:48 -080027 }
28 if s != len(t) {
Rob Pike325cf8e2010-03-24 16:46:53 -070029 println("bad defer", s)
30 panic("fail")
Russ Cox6ee6d6e2009-01-28 16:58:48 -080031 }
32}
33
Russ Cox1fa41732011-02-01 18:34:41 -050034func f0() {
35 // likely to make a new stack for f0,
36 // because the call to f1 puts 3000 bytes
37 // in our frame.
38 f1()
39}
40
41func f1() [3000]byte {
42 // likely to make a new stack for f1,
43 // because 3000 bytes were used by f0
44 // and we need 3000 more for the call
45 // to f2. if the call to morestack in f1
46 // does not pass the frame size, the new
47 // stack (default size 5k) will not be big
48 // enough for the frame, and the morestack
49 // check in f2 will die, if we get that far
50 // without faulting.
51 f2()
52 return [3000]byte{}
53}
54
55func f2() [3000]byte {
56 // just take up space
57 return [3000]byte{}
58}
59
Rob Pike325cf8e2010-03-24 16:46:53 -070060var c = make(chan int)
61var t T
62var b = []byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
Russ Cox6ee6d6e2009-01-28 16:58:48 -080063
64func recur(n int) {
Rob Pike325cf8e2010-03-24 16:46:53 -070065 ss := string(b)
Russ Cox78edbfd2009-04-10 06:22:41 -070066 if len(ss) != len(b) {
Rob Pike325cf8e2010-03-24 16:46:53 -070067 panic("bad []byte -> string")
Russ Cox78edbfd2009-04-10 06:22:41 -070068 }
Rob Pike325cf8e2010-03-24 16:46:53 -070069 go g(c, t)
Russ Cox1fa41732011-02-01 18:34:41 -050070 f0()
Rob Pike325cf8e2010-03-24 16:46:53 -070071 s := <-c
Russ Cox6ee6d6e2009-01-28 16:58:48 -080072 if s != len(t) {
Rob Pike325cf8e2010-03-24 16:46:53 -070073 println("bad go", s)
74 panic("fail")
Russ Cox6ee6d6e2009-01-28 16:58:48 -080075 }
Russ Cox0f4f2a62009-02-06 13:46:56 -080076 f := func(t T) int {
Rob Pike325cf8e2010-03-24 16:46:53 -070077 s := 0
Russ Cox0f4f2a62009-02-06 13:46:56 -080078 for i := 0; i < len(t); i++ {
Rob Pike325cf8e2010-03-24 16:46:53 -070079 s += t[i]
Russ Cox0f4f2a62009-02-06 13:46:56 -080080 }
Rob Pike325cf8e2010-03-24 16:46:53 -070081 s += n
82 return s
83 }
84 s = f(t)
85 if s != len(t)+n {
86 println("bad func", s, "at level", n)
87 panic("fail")
Russ Cox0f4f2a62009-02-06 13:46:56 -080088 }
Russ Cox6ee6d6e2009-01-28 16:58:48 -080089 if n > 0 {
Rob Pike325cf8e2010-03-24 16:46:53 -070090 recur(n - 1)
Russ Cox6ee6d6e2009-01-28 16:58:48 -080091 }
Rob Pike325cf8e2010-03-24 16:46:53 -070092 defer d(t)
Russ Cox6ee6d6e2009-01-28 16:58:48 -080093}
94
95func main() {
96 for i := 0; i < len(t); i++ {
Rob Pike325cf8e2010-03-24 16:46:53 -070097 t[i] = 1
Russ Cox6ee6d6e2009-01-28 16:58:48 -080098 }
Russ Coxc6138ef2010-04-22 17:52:22 -070099 recur(8000)
Russ Cox6ee6d6e2009-01-28 16:58:48 -0800100}