go/test/fixedbugs/issue11656.go
Michael Munday 1a82946ea5 test/fixedbugs: add s390x case to issue11656
An instruction consisting of all 0s causes an illegal instruction
signal on s390x. Since 0s are the default in this test this CL just
makes it explicit.

Change-Id: Id6e060eed1a588f4b10a4e4861709fcd19b434ac
Reviewed-on: https://go-review.googlesource.com/20962
Reviewed-by: Minux Ma <minux@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2016-03-21 07:09:36 +00:00

77 lines
1.8 KiB
Go

// run
// Copyright 2015 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.
// windows doesn't work, because Windows exception handling
// delivers signals based on the current PC, and that current PC
// doesn't go into the Go runtime.
// +build !windows
package main
import (
"encoding/binary"
"runtime"
"runtime/debug"
"unsafe"
)
func main() {
debug.SetPanicOnFault(true)
defer func() {
if err := recover(); err == nil {
panic("not panicking")
}
pc, _, _, _ := runtime.Caller(10)
f := runtime.FuncForPC(pc)
if f == nil || f.Name() != "main.f" {
if f == nil {
println("no func for ", unsafe.Pointer(pc))
} else {
println("found func:", f.Name())
}
panic("cannot find main.f on stack")
}
}()
f(20)
}
func f(n int) {
if n > 0 {
f(n - 1)
}
var f struct {
x uintptr
}
// We want to force an illegal instruction, to get a crash
// at a PC value != 0.
// Not all systems make the data section non-executable.
ill := make([]byte, 64)
switch runtime.GOARCH {
case "386", "amd64":
binary.LittleEndian.PutUint16(ill, 0x0b0f) // ud2
case "arm":
binary.LittleEndian.PutUint32(ill, 0xe7f000f0) // no name, but permanently undefined
case "arm64":
binary.LittleEndian.PutUint32(ill, 0xd4207d00) // brk #1000
case "ppc64":
binary.BigEndian.PutUint32(ill, 0x7fe00008) // trap
case "ppc64le":
binary.LittleEndian.PutUint32(ill, 0x7fe00008) // trap
case "mips64":
binary.BigEndian.PutUint32(ill, 0x00000034) // trap
case "mips64le":
binary.LittleEndian.PutUint32(ill, 0x00000034) // trap
case "s390x":
binary.BigEndian.PutUint32(ill, 0) // undefined instruction
default:
// Just leave it as 0 and hope for the best.
}
f.x = uintptr(unsafe.Pointer(&ill[0]))
fn := *(*func())(unsafe.Pointer(&f))
fn()
}