| // Copyright 2015 The Go Authors. All rights reserved. | |
| // Use of this source code is governed by a BSD-style | |
| // license that can be found in the LICENSE file. | |
| package main | |
| import ( | |
| "fmt" | |
| "runtime" | |
| "runtime/debug" | |
| "time" | |
| ) | |
| func init() { | |
| registerInit("InitDeadlock", InitDeadlock) | |
| registerInit("NoHelperGoroutines", NoHelperGoroutines) | |
| register("SimpleDeadlock", SimpleDeadlock) | |
| register("LockedDeadlock", LockedDeadlock) | |
| register("LockedDeadlock2", LockedDeadlock2) | |
| register("GoexitDeadlock", GoexitDeadlock) | |
| register("StackOverflow", StackOverflow) | |
| register("ThreadExhaustion", ThreadExhaustion) | |
| register("RecursivePanic", RecursivePanic) | |
| register("GoexitExit", GoexitExit) | |
| register("GoNil", GoNil) | |
| register("MainGoroutineID", MainGoroutineID) | |
| register("Breakpoint", Breakpoint) | |
| register("GoexitInPanic", GoexitInPanic) | |
| register("PanicAfterGoexit", PanicAfterGoexit) | |
| register("RecoveredPanicAfterGoexit", RecoveredPanicAfterGoexit) | |
| register("PanicTraceback", PanicTraceback) | |
| register("GoschedInPanic", GoschedInPanic) | |
| register("SyscallInPanic", SyscallInPanic) | |
| register("PanicLoop", PanicLoop) | |
| } | |
| func SimpleDeadlock() { | |
| select {} | |
| panic("not reached") | |
| } | |
| func InitDeadlock() { | |
| select {} | |
| panic("not reached") | |
| } | |
| func LockedDeadlock() { | |
| runtime.LockOSThread() | |
| select {} | |
| } | |
| func LockedDeadlock2() { | |
| go func() { | |
| runtime.LockOSThread() | |
| select {} | |
| }() | |
| time.Sleep(time.Millisecond) | |
| select {} | |
| } | |
| func GoexitDeadlock() { | |
| F := func() { | |
| for i := 0; i < 10; i++ { | |
| } | |
| } | |
| go F() | |
| go F() | |
| runtime.Goexit() | |
| } | |
| func StackOverflow() { | |
| var f func() byte | |
| f = func() byte { | |
| var buf [64 << 10]byte | |
| return buf[0] + f() | |
| } | |
| debug.SetMaxStack(1474560) | |
| f() | |
| } | |
| func ThreadExhaustion() { | |
| debug.SetMaxThreads(10) | |
| c := make(chan int) | |
| for i := 0; i < 100; i++ { | |
| go func() { | |
| runtime.LockOSThread() | |
| c <- 0 | |
| select {} | |
| }() | |
| <-c | |
| } | |
| } | |
| func RecursivePanic() { | |
| func() { | |
| defer func() { | |
| fmt.Println(recover()) | |
| }() | |
| var x [8192]byte | |
| func(x [8192]byte) { | |
| defer func() { | |
| if err := recover(); err != nil { | |
| panic("wrap: " + err.(string)) | |
| } | |
| }() | |
| panic("bad") | |
| }(x) | |
| }() | |
| panic("again") | |
| } | |
| func GoexitExit() { | |
| go func() { | |
| time.Sleep(time.Millisecond) | |
| }() | |
| i := 0 | |
| runtime.SetFinalizer(&i, func(p *int) {}) | |
| runtime.GC() | |
| runtime.Goexit() | |
| } | |
| func GoNil() { | |
| defer func() { | |
| recover() | |
| }() | |
| var f func() | |
| go f() | |
| select {} | |
| } | |
| func MainGoroutineID() { | |
| panic("test") | |
| } | |
| func NoHelperGoroutines() { | |
| i := 0 | |
| runtime.SetFinalizer(&i, func(p *int) {}) | |
| time.AfterFunc(time.Hour, func() {}) | |
| panic("oops") | |
| } | |
| func Breakpoint() { | |
| runtime.Breakpoint() | |
| } | |
| func GoexitInPanic() { | |
| go func() { | |
| defer func() { | |
| runtime.Goexit() | |
| }() | |
| panic("hello") | |
| }() | |
| runtime.Goexit() | |
| } | |
| type errorThatGosched struct{} | |
| func (errorThatGosched) Error() string { | |
| runtime.Gosched() | |
| return "errorThatGosched" | |
| } | |
| func GoschedInPanic() { | |
| panic(errorThatGosched{}) | |
| } | |
| type errorThatPrint struct{} | |
| func (errorThatPrint) Error() string { | |
| fmt.Println("1") | |
| fmt.Println("2") | |
| return "3" | |
| } | |
| func SyscallInPanic() { | |
| panic(errorThatPrint{}) | |
| } | |
| func PanicAfterGoexit() { | |
| defer func() { | |
| panic("hello") | |
| }() | |
| runtime.Goexit() | |
| } | |
| func RecoveredPanicAfterGoexit() { | |
| defer func() { | |
| defer func() { | |
| r := recover() | |
| if r == nil { | |
| panic("bad recover") | |
| } | |
| }() | |
| panic("hello") | |
| }() | |
| runtime.Goexit() | |
| } | |
| func PanicTraceback() { | |
| pt1() | |
| } | |
| func pt1() { | |
| defer func() { | |
| panic("panic pt1") | |
| }() | |
| pt2() | |
| } | |
| func pt2() { | |
| defer func() { | |
| panic("panic pt2") | |
| }() | |
| panic("hello") | |
| } | |
| type panicError struct{} | |
| func (*panicError) Error() string { | |
| panic("double error") | |
| } | |
| func PanicLoop() { | |
| panic(&panicError{}) | |
| } |