// Copyright 2018 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. package main import ( "runtime" "runtime/debug" "unsafe" ) func init() { register("BadTraceback", BadTraceback) } func BadTraceback() { // Disable GC to prevent traceback at unexpected time. debug.SetGCPercent(-1) // Out of an abundance of caution, also make sure that there are // no GCs actively in progress. runtime.GC() // Run badLR1 on its own stack to minimize the stack size and // exercise the stack bounds logic in the hex dump. go badLR1() select {} } //go:noinline func badLR1() { // We need two frames on LR machines because we'll smash this // frame's saved LR. badLR2(0) } //go:noinline func badLR2(arg int) { // Smash the return PC or saved LR. lrOff := unsafe.Sizeof(uintptr(0)) if runtime.GOARCH == "ppc64" || runtime.GOARCH == "ppc64le" { lrOff = 32 // FIXED_FRAME or sys.MinFrameSize } lrPtr := (*uintptr)(unsafe.Pointer(uintptr(unsafe.Pointer(&arg)) - lrOff)) *lrPtr = 0xbad // Print a backtrace. This should include diagnostics for the // bad return PC and a hex dump. panic("backtrace") }