Source file test/fixedbugs/issue11656.dir/issue11656.go

     1  // Copyright 2015 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  	"encoding/binary"
     9  	"runtime"
    10  	"runtime/debug"
    11  	"unsafe"
    12  )
    13  
    14  func main() {
    15  	debug.SetPanicOnFault(true)
    16  	defer func() {
    17  		if err := recover(); err == nil {
    18  			panic("not panicking")
    19  		}
    20  		pc, _, _, _ := runtime.Caller(10)
    21  		f := runtime.FuncForPC(pc)
    22  		if f == nil || f.Name() != "main.f" {
    23  			if f == nil {
    24  				println("no func for ", unsafe.Pointer(pc))
    25  			} else {
    26  				println("found func:", f.Name())
    27  			}
    28  			panic("cannot find main.f on stack")
    29  		}
    30  	}()
    31  	f(20)
    32  }
    33  
    34  func f(n int) {
    35  	if n > 0 {
    36  		f(n - 1)
    37  	}
    38  	var f struct {
    39  		x uintptr
    40  	}
    41  
    42  	// We want to force a seg fault, to get a crash at a PC value != 0.
    43  	// Not all systems make the data section non-executable.
    44  	ill := make([]byte, 64)
    45  	switch runtime.GOARCH {
    46  	case "386", "amd64":
    47  		ill = append(ill[:0], 0x89, 0x04, 0x25, 0x00, 0x00, 0x00, 0x00) // MOVL AX, 0
    48  	case "arm":
    49  		binary.LittleEndian.PutUint32(ill[0:4], 0xe3a00000) // MOVW $0, R0
    50  		binary.LittleEndian.PutUint32(ill[4:8], 0xe5800000) // MOVW R0, (R0)
    51  	case "arm64":
    52  		binary.LittleEndian.PutUint32(ill, 0xf90003ff) // MOVD ZR, (ZR)
    53  	case "ppc64":
    54  		binary.BigEndian.PutUint32(ill, 0xf8000000) // MOVD R0, (R0)
    55  	case "ppc64le":
    56  		binary.LittleEndian.PutUint32(ill, 0xf8000000) // MOVD R0, (R0)
    57  	case "mips", "mips64":
    58  		binary.BigEndian.PutUint32(ill, 0xfc000000) // MOVV R0, (R0)
    59  	case "mipsle", "mips64le":
    60  		binary.LittleEndian.PutUint32(ill, 0xfc000000) // MOVV R0, (R0)
    61  	case "s390x":
    62  		ill = append(ill[:0], 0xa7, 0x09, 0x00, 0x00)         // MOVD $0, R0
    63  		ill = append(ill, 0xe3, 0x00, 0x00, 0x00, 0x00, 0x24) // MOVD R0, (R0)
    64  	case "riscv64":
    65  		binary.LittleEndian.PutUint32(ill, 0x00003023) // MOV X0, (X0)
    66  	default:
    67  		// Just leave it as 0 and hope for the best.
    68  	}
    69  
    70  	f.x = uintptr(unsafe.Pointer(&ill[0]))
    71  	p := &f
    72  	fn := *(*func())(unsafe.Pointer(&p))
    73  	syncIcache(f.x)
    74  	fn()
    75  }
    76  

View as plain text