diff --git a/c/signal/signal.go b/c/signal/signal.go new file mode 100644 index 00000000..5be95f97 --- /dev/null +++ b/c/signal/signal.go @@ -0,0 +1,32 @@ +package signal + +import ( + "unsafe" + + "github.com/goplus/llgo/c" +) +import "C" + +const ( + LLGoPackage = "link" +) + +//llgo:type C +type SignalHandler func(c.Int) + +//llgo:type C +type sigactiont struct { + handler SignalHandler + tramp unsafe.Pointer + mask c.Int + flags c.Int +} + +//go:linkname sigaction C.sigaction +func sigaction(sig c.Int, act, old *sigactiont) c.Int + +func Signal(sig c.Int, hanlder SignalHandler) c.Int { + var act sigactiont + act.handler = hanlder + return sigaction(sig, &act, nil) +} diff --git a/cl/_testgo/sigsegv/in.go b/cl/_testgo/sigsegv/in.go new file mode 100644 index 00000000..b1e3e7e6 --- /dev/null +++ b/cl/_testgo/sigsegv/in.go @@ -0,0 +1,24 @@ +package main + +type T struct { + s int +} + +func f() *T { + return nil +} + +func init() { + println("init") + defer func() { + r := recover() + if e, ok := r.(error); ok { + println("recover", e.Error()) + } + }() + println(f().s) +} + +func main() { + println("main") +} diff --git a/cl/_testgo/sigsegv/out.ll b/cl/_testgo/sigsegv/out.ll new file mode 100644 index 00000000..1c8a0e79 --- /dev/null +++ b/cl/_testgo/sigsegv/out.ll @@ -0,0 +1 @@ +; \ No newline at end of file diff --git a/internal/runtime/z_rt.go b/internal/runtime/z_rt.go index c11ebb6c..d6f54486 100644 --- a/internal/runtime/z_rt.go +++ b/internal/runtime/z_rt.go @@ -21,6 +21,8 @@ import ( "github.com/goplus/llgo/c" "github.com/goplus/llgo/c/pthread" + "github.com/goplus/llgo/c/signal" + "github.com/goplus/llgo/c/syscall" ) // ----------------------------------------------------------------------------- @@ -116,4 +118,16 @@ const MaxZero = 1024 var ZeroVal [MaxZero]byte +func init() { + signal.Signal(c.Int(syscall.SIGSEGV), func(v c.Int) { + switch syscall.Signal(v) { + case syscall.SIGSEGV: + panic(errorString("invalid memory address or nil pointer dereference")) + default: + var buf [20]byte + panic(errorString("unexpected signal value: " + string(itoa(buf[:], uint64(v))))) + } + }) +} + // -----------------------------------------------------------------------------