Home | History | Annotate | Download | only in 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 // darwin/386 seems to mangle the PC and SP before
      8 // it manages to invoke the signal handler, so this test fails there.
      9 // +build !darwin !386
     10 //
     11 // openbsd/386 and netbsd/386 don't work, not sure why.
     12 // +build !openbsd !386
     13 // +build !netbsd !386
     14 //
     15 // windows doesn't work, because Windows exception handling
     16 // delivers signals based on the current PC, and that current PC
     17 // doesn't go into the Go runtime.
     18 // +build !windows
     19 //
     20 // arm64 gets "illegal instruction" (why is the data executable?)
     21 // and is unable to do the traceback correctly (why?).
     22 // +build !arm64
     23 
     24 package main
     25 
     26 import (
     27 	"runtime"
     28 	"runtime/debug"
     29 	"unsafe"
     30 )
     31 
     32 func main() {
     33 	debug.SetPanicOnFault(true)
     34 	defer func() {
     35 		if err := recover(); err == nil {
     36 			panic("not panicking")
     37 		}
     38 		pc, _, _, _ := runtime.Caller(10)
     39 		f := runtime.FuncForPC(pc)
     40 		if f == nil || f.Name() != "main.f" {
     41 			if f == nil {
     42 				println("no func for ", unsafe.Pointer(pc))
     43 			} else {
     44 				println("found func:", f.Name())
     45 			}
     46 			panic("cannot find main.f on stack")
     47 		}
     48 	}()
     49 	f(20)
     50 }
     51 
     52 func f(n int) {
     53 	if n > 0 {
     54 		f(n - 1)
     55 	}
     56 	var f struct {
     57 		x uintptr
     58 	}
     59 	f.x = uintptr(unsafe.Pointer(&f))
     60 	fn := *(*func())(unsafe.Pointer(&f))
     61 	fn()
     62 }
     63