47 lines
1.1 KiB
Go
47 lines
1.1 KiB
Go
// 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)
|
|
|
|
// 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")
|
|
}
|