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 5package main 6 7import ( 8 "runtime" 9 "runtime/debug" 10 "unsafe" 11) 12 13func init() { 14 register("BadTraceback", BadTraceback) 15} 16 17func 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 31func 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 38func 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