github.com/go-darwin/sys@v0.0.0-20220510002607-68fd01f054ca/testdata/testprog/badtraceback.go (about)

     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  
    21  	// Run badLR1 on its own stack to minimize the stack size and
    22  	// exercise the stack bounds logic in the hex dump.
    23  	go badLR1()
    24  	select {}
    25  }
    26  
    27  //go:noinline
    28  func badLR1() {
    29  	// We need two frames on LR machines because we'll smash this
    30  	// frame's saved LR.
    31  	badLR2(0)
    32  }
    33  
    34  //go:noinline
    35  func badLR2(arg int) {
    36  	// Smash the return PC or saved LR.
    37  	lrOff := unsafe.Sizeof(uintptr(0))
    38  	if runtime.GOARCH == "ppc64" || runtime.GOARCH == "ppc64le" {
    39  		lrOff = 32 // FIXED_FRAME or sys.MinFrameSize
    40  	}
    41  	lrPtr := (*uintptr)(unsafe.Pointer(uintptr(unsafe.Pointer(&arg)) - lrOff))
    42  	*lrPtr = 0xbad
    43  
    44  	// Print a backtrace. This should include diagnostics for the
    45  	// bad return PC and a hex dump.
    46  	panic("backtrace")
    47  }