Home | History | Annotate | Download | only in test
      1 // run
      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 // Test stack splitting code.
      8 // Try to tickle stack splitting bugs by doing
      9 // go, defer, and closure calls at different stack depths.
     10 
     11 package main
     12 
     13 type T [20]int
     14 
     15 func g(c chan int, t T) {
     16 	s := 0
     17 	for i := 0; i < len(t); i++ {
     18 		s += t[i]
     19 	}
     20 	c <- s
     21 }
     22 
     23 func d(t T) {
     24 	s := 0
     25 	for i := 0; i < len(t); i++ {
     26 		s += t[i]
     27 	}
     28 	if s != len(t) {
     29 		println("bad defer", s)
     30 		panic("fail")
     31 	}
     32 }
     33 
     34 func 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 
     41 func 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 
     55 func f2() [3000]byte {
     56 	// just take up space
     57 	return [3000]byte{}
     58 }
     59 
     60 var c = make(chan int)
     61 var t T
     62 var b = []byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
     63 
     64 func recur(n int) {
     65 	ss := string(b)
     66 	if len(ss) != len(b) {
     67 		panic("bad []byte -> string")
     68 	}
     69 	go g(c, t)
     70 	f0()
     71 	s := <-c
     72 	if s != len(t) {
     73 		println("bad go", s)
     74 		panic("fail")
     75 	}
     76 	f := func(t T) int {
     77 		s := 0
     78 		for i := 0; i < len(t); i++ {
     79 			s += t[i]
     80 		}
     81 		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")
     88 	}
     89 	if n > 0 {
     90 		recur(n - 1)
     91 	}
     92 	defer d(t)
     93 }
     94 
     95 func main() {
     96 	for i := 0; i < len(t); i++ {
     97 		t[i] = 1
     98 	}
     99 	recur(8000)
    100 }
    101