blob: 1fd57161ff2903aff1bd3b15ff38cff561e8f8a1 [file] [log] [blame]
Russ Cox6ee6d6e2009-01-28 16:58:48 -08001// $G $D/$F.go && $L $F.$A && ./$A.out
2
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
7// Try to tickle stack splitting bugs by doing
Russ Cox0f4f2a62009-02-06 13:46:56 -08008// go, defer, and closure calls at different stack depths.
Russ Cox6ee6d6e2009-01-28 16:58:48 -08009
10package main
11
Rob Pike325cf8e2010-03-24 16:46:53 -070012type T [20]int
Russ Cox6ee6d6e2009-01-28 16:58:48 -080013
14func g(c chan int, t T) {
Rob Pike325cf8e2010-03-24 16:46:53 -070015 s := 0
Russ Cox6ee6d6e2009-01-28 16:58:48 -080016 for i := 0; i < len(t); i++ {
Rob Pike325cf8e2010-03-24 16:46:53 -070017 s += t[i]
Russ Cox6ee6d6e2009-01-28 16:58:48 -080018 }
Rob Pike325cf8e2010-03-24 16:46:53 -070019 c <- s
Russ Cox6ee6d6e2009-01-28 16:58:48 -080020}
21
22func d(t T) {
Rob Pike325cf8e2010-03-24 16:46:53 -070023 s := 0
Russ Cox6ee6d6e2009-01-28 16:58:48 -080024 for i := 0; i < len(t); i++ {
Rob Pike325cf8e2010-03-24 16:46:53 -070025 s += t[i]
Russ Cox6ee6d6e2009-01-28 16:58:48 -080026 }
27 if s != len(t) {
Rob Pike325cf8e2010-03-24 16:46:53 -070028 println("bad defer", s)
29 panic("fail")
Russ Cox6ee6d6e2009-01-28 16:58:48 -080030 }
31}
32
Russ Cox1fa41732011-02-01 18:34:41 -050033func f0() {
34 // likely to make a new stack for f0,
35 // because the call to f1 puts 3000 bytes
36 // in our frame.
37 f1()
38}
39
40func f1() [3000]byte {
41 // likely to make a new stack for f1,
42 // because 3000 bytes were used by f0
43 // and we need 3000 more for the call
44 // to f2. if the call to morestack in f1
45 // does not pass the frame size, the new
46 // stack (default size 5k) will not be big
47 // enough for the frame, and the morestack
48 // check in f2 will die, if we get that far
49 // without faulting.
50 f2()
51 return [3000]byte{}
52}
53
54func f2() [3000]byte {
55 // just take up space
56 return [3000]byte{}
57}
58
Rob Pike325cf8e2010-03-24 16:46:53 -070059var c = make(chan int)
60var t T
61var b = []byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
Russ Cox6ee6d6e2009-01-28 16:58:48 -080062
63func recur(n int) {
Rob Pike325cf8e2010-03-24 16:46:53 -070064 ss := string(b)
Russ Cox78edbfd2009-04-10 06:22:41 -070065 if len(ss) != len(b) {
Rob Pike325cf8e2010-03-24 16:46:53 -070066 panic("bad []byte -> string")
Russ Cox78edbfd2009-04-10 06:22:41 -070067 }
Rob Pike325cf8e2010-03-24 16:46:53 -070068 go g(c, t)
Russ Cox1fa41732011-02-01 18:34:41 -050069 f0()
Rob Pike325cf8e2010-03-24 16:46:53 -070070 s := <-c
Russ Cox6ee6d6e2009-01-28 16:58:48 -080071 if s != len(t) {
Rob Pike325cf8e2010-03-24 16:46:53 -070072 println("bad go", s)
73 panic("fail")
Russ Cox6ee6d6e2009-01-28 16:58:48 -080074 }
Russ Cox0f4f2a62009-02-06 13:46:56 -080075 f := func(t T) int {
Rob Pike325cf8e2010-03-24 16:46:53 -070076 s := 0
Russ Cox0f4f2a62009-02-06 13:46:56 -080077 for i := 0; i < len(t); i++ {
Rob Pike325cf8e2010-03-24 16:46:53 -070078 s += t[i]
Russ Cox0f4f2a62009-02-06 13:46:56 -080079 }
Rob Pike325cf8e2010-03-24 16:46:53 -070080 s += n
81 return s
82 }
83 s = f(t)
84 if s != len(t)+n {
85 println("bad func", s, "at level", n)
86 panic("fail")
Russ Cox0f4f2a62009-02-06 13:46:56 -080087 }
Russ Cox6ee6d6e2009-01-28 16:58:48 -080088 if n > 0 {
Rob Pike325cf8e2010-03-24 16:46:53 -070089 recur(n - 1)
Russ Cox6ee6d6e2009-01-28 16:58:48 -080090 }
Rob Pike325cf8e2010-03-24 16:46:53 -070091 defer d(t)
Russ Cox6ee6d6e2009-01-28 16:58:48 -080092}
93
94func main() {
95 for i := 0; i < len(t); i++ {
Rob Pike325cf8e2010-03-24 16:46:53 -070096 t[i] = 1
Russ Cox6ee6d6e2009-01-28 16:58:48 -080097 }
Russ Coxc6138ef2010-04-22 17:52:22 -070098 recur(8000)
Russ Cox6ee6d6e2009-01-28 16:58:48 -080099}