...
Run Format

Source file test/fixedbugs/issue11656.go

Documentation: test/fixedbugs

     1  // run
     2  
     3  // Copyright 2015 The Go Authors. All rights reserved.
     4  // Use of this source code is governed by a BSD-style
     5  // license that can be found in the LICENSE file.
     6  
     7  // windows doesn't work, because Windows exception handling
     8  // delivers signals based on the current PC, and that current PC
     9  // doesn't go into the Go runtime.
    10  // +build !windows
    11  
    12  // wasm does not work, because the linear memory is not executable.
    13  // +build !wasm
    14  
    15  package main
    16  
    17  import (
    18  	"encoding/binary"
    19  	"runtime"
    20  	"runtime/debug"
    21  	"unsafe"
    22  )
    23  
    24  func main() {
    25  	debug.SetPanicOnFault(true)
    26  	defer func() {
    27  		if err := recover(); err == nil {
    28  			panic("not panicking")
    29  		}
    30  		pc, _, _, _ := runtime.Caller(10)
    31  		f := runtime.FuncForPC(pc)
    32  		if f == nil || f.Name() != "main.f" {
    33  			if f == nil {
    34  				println("no func for ", unsafe.Pointer(pc))
    35  			} else {
    36  				println("found func:", f.Name())
    37  			}
    38  			panic("cannot find main.f on stack")
    39  		}
    40  	}()
    41  	f(20)
    42  }
    43  
    44  func f(n int) {
    45  	if n > 0 {
    46  		f(n - 1)
    47  	}
    48  	var f struct {
    49  		x uintptr
    50  	}
    51  
    52  	// We want to force an illegal instruction, to get a crash
    53  	// at a PC value != 0.
    54  	// Not all systems make the data section non-executable.
    55  	ill := make([]byte, 64)
    56  	switch runtime.GOARCH {
    57  	case "386", "amd64":
    58  		binary.LittleEndian.PutUint16(ill, 0x0b0f) // ud2
    59  	case "arm":
    60  		binary.LittleEndian.PutUint32(ill, 0xe7f000f0) // no name, but permanently undefined
    61  	case "arm64":
    62  		binary.LittleEndian.PutUint32(ill, 0xd4207d00) // brk #1000
    63  	case "ppc64":
    64  		binary.BigEndian.PutUint32(ill, 0x7fe00008) // trap
    65  	case "ppc64le":
    66  		binary.LittleEndian.PutUint32(ill, 0x7fe00008) // trap
    67  	case "mips", "mips64":
    68  		binary.BigEndian.PutUint32(ill, 0x00000034) // trap
    69  	case "mipsle", "mips64le":
    70  		binary.LittleEndian.PutUint32(ill, 0x00000034) // trap
    71  	case "s390x":
    72  		binary.BigEndian.PutUint32(ill, 0) // undefined instruction
    73  	default:
    74  		// Just leave it as 0 and hope for the best.
    75  	}
    76  
    77  	f.x = uintptr(unsafe.Pointer(&ill[0]))
    78  	fn := *(*func())(unsafe.Pointer(&f))
    79  	fn()
    80  }
    81  

View as plain text