1 // Copyright 2018 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 "runtime" 9 "runtime/debug" 10 "unsafe" 11 ) 12 13 func init() { 14 register("BadTraceback", BadTraceback) 15 } 16 17 func BadTraceback() { 18 // Disable GC to prevent traceback at unexpected time. 19 debug.SetGCPercent(-1) 20 // Out of an abundance of caution, also make sure that there are 21 // no GCs actively in progress. 22 runtime.GC() 23 24 // Run badLR1 on its own stack to minimize the stack size and 25 // exercise the stack bounds logic in the hex dump. 26 go badLR1() 27 select {} 28 } 29 30 //go:noinline 31 func badLR1() { 32 // We need two frames on LR machines because we'll smash this 33 // frame's saved LR. 34 badLR2(0) 35 } 36 37 //go:noinline 38 func badLR2(arg int) { 39 // Smash the return PC or saved LR. 40 lrOff := unsafe.Sizeof(uintptr(0)) 41 if runtime.GOARCH == "ppc64" || runtime.GOARCH == "ppc64le" { 42 lrOff = 32 // FIXED_FRAME or sys.MinFrameSize 43 } 44 lrPtr := (*uintptr)(unsafe.Pointer(uintptr(unsafe.Pointer(&arg)) - lrOff)) 45 *lrPtr = 0xbad 46 47 // Print a backtrace. This should include diagnostics for the 48 // bad return PC and a hex dump. 49 panic("backtrace") 50 } 51