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 5package main 6 7import ( 8 "fmt" 9 "runtime" 10) 11 12func 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} 23 24func test(name string) { 25 defer func() { 26 if x := recover(); x != nil { 27 fmt.Printf(" recovered") 28 } 29 fmt.Printf(" done\n") 30 }() 31 fmt.Printf("%s:", name) 32 var s *string 33 _ = *s 34 fmt.Print("SHOULD NOT BE HERE") 35} 36 37func testInNewThread(name string) { 38 c := make(chan bool) 39 go func() { 40 runtime.LockOSThread() 41 test(name) 42 c <- true 43 }() 44 <-c 45} 46 47func Crash() { 48 runtime.LockOSThread() 49 test("main") 50 testInNewThread("new-thread") 51 testInNewThread("second-new-thread") 52 test("main-again") 53} 54 55type P string 56 57func (p P) String() string { 58 // Try to free the "YYY" string header when the "XXX" 59 // panic is stringified. 60 runtime.GC() 61 runtime.GC() 62 runtime.GC() 63 return string(p) 64} 65 66// Test that panic message is not clobbered. 67// See issue 30150. 68func DoublePanic() { 69 defer func() { 70 panic(P("YYY")) 71 }() 72 panic(P("XXX")) 73} 74 75// Test that panic while panicking discards error message 76// See issue 52257 77type exampleError struct{} 78 79func (e exampleError) Error() string { 80 panic("important multi-line\nerror message") 81} 82 83func ErrorPanic() { 84 panic(exampleError{}) 85} 86 87type examplePanicError struct{} 88 89func (e examplePanicError) Error() string { 90 panic(exampleError{}) 91} 92 93func DoubleErrorPanic() { 94 panic(examplePanicError{}) 95} 96 97type exampleStringer struct{} 98 99func (s exampleStringer) String() string { 100 panic("important multi-line\nstringer message") 101} 102 103func StringerPanic() { 104 panic(exampleStringer{}) 105} 106 107type examplePanicStringer struct{} 108 109func (s examplePanicStringer) String() string { 110 panic(exampleStringer{}) 111} 112 113func DoubleStringerPanic() { 114 panic(examplePanicStringer{}) 115} 116 117func StringPanic() { 118 panic("important multi-line\nstring message") 119} 120 121func NilPanic() { 122 panic(nil) 123} 124 125type exampleCircleStartError struct{} 126 127func (e exampleCircleStartError) Error() string { 128 panic(exampleCircleEndError{}) 129} 130 131type exampleCircleEndError struct{} 132 133func (e exampleCircleEndError) Error() string { 134 panic(exampleCircleStartError{}) 135} 136 137func CircularPanic() { 138 panic(exampleCircleStartError{}) 139} 140