Home | History | Annotate | Download | only in testprog
      1 // Copyright 2015 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.
      4 
      5 package main
      6 
      7 import (
      8 	"fmt"
      9 	"runtime"
     10 	"runtime/debug"
     11 	"time"
     12 )
     13 
     14 func init() {
     15 	registerInit("InitDeadlock", InitDeadlock)
     16 	registerInit("NoHelperGoroutines", NoHelperGoroutines)
     17 
     18 	register("SimpleDeadlock", SimpleDeadlock)
     19 	register("LockedDeadlock", LockedDeadlock)
     20 	register("LockedDeadlock2", LockedDeadlock2)
     21 	register("GoexitDeadlock", GoexitDeadlock)
     22 	register("StackOverflow", StackOverflow)
     23 	register("ThreadExhaustion", ThreadExhaustion)
     24 	register("RecursivePanic", RecursivePanic)
     25 	register("GoexitExit", GoexitExit)
     26 	register("GoNil", GoNil)
     27 	register("MainGoroutineID", MainGoroutineID)
     28 	register("Breakpoint", Breakpoint)
     29 	register("GoexitInPanic", GoexitInPanic)
     30 	register("PanicAfterGoexit", PanicAfterGoexit)
     31 	register("RecoveredPanicAfterGoexit", RecoveredPanicAfterGoexit)
     32 	register("PanicTraceback", PanicTraceback)
     33 	register("GoschedInPanic", GoschedInPanic)
     34 	register("SyscallInPanic", SyscallInPanic)
     35 	register("PanicLoop", PanicLoop)
     36 }
     37 
     38 func SimpleDeadlock() {
     39 	select {}
     40 	panic("not reached")
     41 }
     42 
     43 func InitDeadlock() {
     44 	select {}
     45 	panic("not reached")
     46 }
     47 
     48 func LockedDeadlock() {
     49 	runtime.LockOSThread()
     50 	select {}
     51 }
     52 
     53 func LockedDeadlock2() {
     54 	go func() {
     55 		runtime.LockOSThread()
     56 		select {}
     57 	}()
     58 	time.Sleep(time.Millisecond)
     59 	select {}
     60 }
     61 
     62 func GoexitDeadlock() {
     63 	F := func() {
     64 		for i := 0; i < 10; i++ {
     65 		}
     66 	}
     67 
     68 	go F()
     69 	go F()
     70 	runtime.Goexit()
     71 }
     72 
     73 func StackOverflow() {
     74 	var f func() byte
     75 	f = func() byte {
     76 		var buf [64 << 10]byte
     77 		return buf[0] + f()
     78 	}
     79 	debug.SetMaxStack(1474560)
     80 	f()
     81 }
     82 
     83 func ThreadExhaustion() {
     84 	debug.SetMaxThreads(10)
     85 	c := make(chan int)
     86 	for i := 0; i < 100; i++ {
     87 		go func() {
     88 			runtime.LockOSThread()
     89 			c <- 0
     90 			select {}
     91 		}()
     92 		<-c
     93 	}
     94 }
     95 
     96 func RecursivePanic() {
     97 	func() {
     98 		defer func() {
     99 			fmt.Println(recover())
    100 		}()
    101 		var x [8192]byte
    102 		func(x [8192]byte) {
    103 			defer func() {
    104 				if err := recover(); err != nil {
    105 					panic("wrap: " + err.(string))
    106 				}
    107 			}()
    108 			panic("bad")
    109 		}(x)
    110 	}()
    111 	panic("again")
    112 }
    113 
    114 func GoexitExit() {
    115 	go func() {
    116 		time.Sleep(time.Millisecond)
    117 	}()
    118 	i := 0
    119 	runtime.SetFinalizer(&i, func(p *int) {})
    120 	runtime.GC()
    121 	runtime.Goexit()
    122 }
    123 
    124 func GoNil() {
    125 	defer func() {
    126 		recover()
    127 	}()
    128 	var f func()
    129 	go f()
    130 	select {}
    131 }
    132 
    133 func MainGoroutineID() {
    134 	panic("test")
    135 }
    136 
    137 func NoHelperGoroutines() {
    138 	i := 0
    139 	runtime.SetFinalizer(&i, func(p *int) {})
    140 	time.AfterFunc(time.Hour, func() {})
    141 	panic("oops")
    142 }
    143 
    144 func Breakpoint() {
    145 	runtime.Breakpoint()
    146 }
    147 
    148 func GoexitInPanic() {
    149 	go func() {
    150 		defer func() {
    151 			runtime.Goexit()
    152 		}()
    153 		panic("hello")
    154 	}()
    155 	runtime.Goexit()
    156 }
    157 
    158 type errorThatGosched struct{}
    159 
    160 func (errorThatGosched) Error() string {
    161 	runtime.Gosched()
    162 	return "errorThatGosched"
    163 }
    164 
    165 func GoschedInPanic() {
    166 	panic(errorThatGosched{})
    167 }
    168 
    169 type errorThatPrint struct{}
    170 
    171 func (errorThatPrint) Error() string {
    172 	fmt.Println("1")
    173 	fmt.Println("2")
    174 	return "3"
    175 }
    176 
    177 func SyscallInPanic() {
    178 	panic(errorThatPrint{})
    179 }
    180 
    181 func PanicAfterGoexit() {
    182 	defer func() {
    183 		panic("hello")
    184 	}()
    185 	runtime.Goexit()
    186 }
    187 
    188 func RecoveredPanicAfterGoexit() {
    189 	defer func() {
    190 		defer func() {
    191 			r := recover()
    192 			if r == nil {
    193 				panic("bad recover")
    194 			}
    195 		}()
    196 		panic("hello")
    197 	}()
    198 	runtime.Goexit()
    199 }
    200 
    201 func PanicTraceback() {
    202 	pt1()
    203 }
    204 
    205 func pt1() {
    206 	defer func() {
    207 		panic("panic pt1")
    208 	}()
    209 	pt2()
    210 }
    211 
    212 func pt2() {
    213 	defer func() {
    214 		panic("panic pt2")
    215 	}()
    216 	panic("hello")
    217 }
    218 
    219 type panicError struct{}
    220 
    221 func (*panicError) Error() string {
    222 	panic("double error")
    223 }
    224 
    225 func PanicLoop() {
    226 	panic(&panicError{})
    227 }
    228