github.com/ltltlt/go-source-code@v0.0.0-20190830023027-95be009773aa/runtime/testdata/testprog/deadlock.go (about)

     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  }