Source file src/runtime/testdata/testprog/crash.go

     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  )
    11  
    12  func init() {
    13  	register("Crash", Crash)
    14  	register("DoublePanic", DoublePanic)
    15  	register("ErrorPanic", ErrorPanic)
    16  	register("StringerPanic", StringerPanic)
    17  	register("DoubleErrorPanic", DoubleErrorPanic)
    18  	register("DoubleStringerPanic", DoubleStringerPanic)
    19  	register("StringPanic", StringPanic)
    20  	register("NilPanic", NilPanic)
    21  	register("CircularPanic", CircularPanic)
    22  	register("ReraisedPanic", ReraisedPanic)
    23  	register("ReraisedMiddlePanic", ReraisedMiddlePanic)
    24  	register("ReraisedPanicSandwich", ReraisedPanicSandwich)
    25  }
    26  
    27  func test(name string) {
    28  	defer func() {
    29  		if x := recover(); x != nil {
    30  			fmt.Printf(" recovered")
    31  		}
    32  		fmt.Printf(" done\n")
    33  	}()
    34  	fmt.Printf("%s:", name)
    35  	var s *string
    36  	_ = *s
    37  	fmt.Print("SHOULD NOT BE HERE")
    38  }
    39  
    40  func testInNewThread(name string) {
    41  	c := make(chan bool)
    42  	go func() {
    43  		runtime.LockOSThread()
    44  		test(name)
    45  		c <- true
    46  	}()
    47  	<-c
    48  }
    49  
    50  func Crash() {
    51  	runtime.LockOSThread()
    52  	test("main")
    53  	testInNewThread("new-thread")
    54  	testInNewThread("second-new-thread")
    55  	test("main-again")
    56  }
    57  
    58  type P string
    59  
    60  func (p P) String() string {
    61  	// Try to free the "YYY" string header when the "XXX"
    62  	// panic is stringified.
    63  	runtime.GC()
    64  	runtime.GC()
    65  	runtime.GC()
    66  	return string(p)
    67  }
    68  
    69  // Test that panic message is not clobbered.
    70  // See issue 30150.
    71  func DoublePanic() {
    72  	defer func() {
    73  		panic(P("YYY"))
    74  	}()
    75  	panic(P("XXX"))
    76  }
    77  
    78  // Test that panic while panicking discards error message
    79  // See issue 52257
    80  type exampleError struct{}
    81  
    82  func (e exampleError) Error() string {
    83  	panic("important multi-line\nerror message")
    84  }
    85  
    86  func ErrorPanic() {
    87  	panic(exampleError{})
    88  }
    89  
    90  type examplePanicError struct{}
    91  
    92  func (e examplePanicError) Error() string {
    93  	panic(exampleError{})
    94  }
    95  
    96  func DoubleErrorPanic() {
    97  	panic(examplePanicError{})
    98  }
    99  
   100  type exampleStringer struct{}
   101  
   102  func (s exampleStringer) String() string {
   103  	panic("important multi-line\nstringer message")
   104  }
   105  
   106  func StringerPanic() {
   107  	panic(exampleStringer{})
   108  }
   109  
   110  type examplePanicStringer struct{}
   111  
   112  func (s examplePanicStringer) String() string {
   113  	panic(exampleStringer{})
   114  }
   115  
   116  func DoubleStringerPanic() {
   117  	panic(examplePanicStringer{})
   118  }
   119  
   120  func StringPanic() {
   121  	panic("important multi-line\nstring message")
   122  }
   123  
   124  func NilPanic() {
   125  	panic(nil)
   126  }
   127  
   128  type exampleCircleStartError struct{}
   129  
   130  func (e exampleCircleStartError) Error() string {
   131  	panic(exampleCircleEndError{})
   132  }
   133  
   134  type exampleCircleEndError struct{}
   135  
   136  func (e exampleCircleEndError) Error() string {
   137  	panic(exampleCircleStartError{})
   138  }
   139  
   140  func CircularPanic() {
   141  	panic(exampleCircleStartError{})
   142  }
   143  
   144  func ReraisedPanic() {
   145  	defer func() {
   146  		panic(recover())
   147  	}()
   148  	panic("message")
   149  }
   150  
   151  func ReraisedMiddlePanic() {
   152  	defer func() {
   153  		recover()
   154  		panic("outer")
   155  	}()
   156  	func() {
   157  		defer func() {
   158  			panic(recover())
   159  		}()
   160  		func() {
   161  			defer func() {
   162  				recover()
   163  				panic("middle")
   164  			}()
   165  			panic("inner")
   166  		}()
   167  	}()
   168  }
   169  
   170  // Panic sandwich:
   171  //
   172  //	panic("outer") =>
   173  //	recovered, panic("inner") =>
   174  //	panic(recovered outer panic value)
   175  //
   176  // Exercises the edge case where we reraise a panic value,
   177  // but with another panic in the middle.
   178  func ReraisedPanicSandwich() {
   179  	var outer any
   180  	defer func() {
   181  		recover()
   182  		panic(outer)
   183  	}()
   184  	func() {
   185  		defer func() {
   186  			outer = recover()
   187  			panic("inner")
   188  		}()
   189  		panic("outer")
   190  	}()
   191  }
   192  

View as plain text