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

View as plain text