/*
int mydiv(int a, int b){
return a/b;
}
*/
import "C"
import (
"fmt"
"runtime"
"sync"
)
func main() {
defer func() {
if r := recover(); r != nil {
fmt.Println("Recovered call to div", r)
}
}()
div()
}
func div() {
var wg sync.WaitGroup
defer func() {
if r := recover(); r != nil {
fmt.Println("Recovered div panic", r)
}
}()
wg.Add(1)
runtime.LockOSThread()
go cgoPanic(&wg)
wg.Wait()
}
func cgoPanic(wg *sync.WaitGroup) {
//Calling C code which panics
fmt.Println(C.mydiv(10, 0))
//panic("Panicking in Go...")
}
This is a sample code for handling C panic in GoLang. But after executing the code,it panics inspite of adding recover in the previous goroutine.
Is there any solution to handle panics in C code that can be caught in GoLang code. It panics saying unexpected signal during cgo execution/runtime execution.
fatal error: unexpected signal during runtime execution
[signal 0xc0000094 code=0x0 addr=0x0 pc=0x4a4c65]
runtime stack:
invalid spdelta 0x4a4c50 0x4a4c65 0x456b7 -1
runtime.gothrow(0x510570, 0x2a)
c:/go/src/runtime/panic.go:503 +0x8e
runtime.sigpanic()
c:/go/src/runtime/os_windows.go:36 +0x65
invalid spdelta 0x4a4c50 0x4a4c65 0x456b7 -1
_cgo_23d1ba16528e_Cfunc_mydiv()
?:0 +0x15
goroutine 5 [syscall, locked to thread]:
runtime.cgocall_errno(0x4a4c50, 0xc08201bf50, 0x0)
c:/go/src/runtime/cgocall.go:130 +0xdb fp=0xc08201bf30 sp=0xc08201bf08
main._Cfunc_mydiv(0xa, 0x0)
_/C_/TESTGO/src/main/_obj/_cgo_gotypes.go:24 +0x4a fp=0xc08201bf50 sp=0xc08201bf30
main.cgoPanic(0xc082004620)
C:/TESTGO/src/main/Testmain.go:48 +0x78 fp=0xc08201bfd8 sp=0xc08201bf50
runtime.goexit()
c:/go/src/runtime/asm_amd64.s:2232 +0x1 fp=0xc08201bfe0 sp=0xc08201bfd8
created by main.div
C:/TESTGO/src/main/Testmain.go:37 +0x85
goroutine 1 [semacquire, locked to thread]:
sync.(*WaitGroup).Wait(0xc082004620)
c:/go/src/sync/waitgroup.go:132 +0x170
main.div()
C:/TESTGO/src/main/Testmain.go:38 +0x95
main.main()
C:/TESTGO/src/main/Testmain.go:23 +0x3c
goroutine 17 [syscall, locked to thread]:
runtime.goexit()
c:/go/src/runtime/asm_amd64.s:2232 +0x1
func div() {
var wg sync.WaitGroup
wg.Add(1)
runtime.LockOSThread()
go func() {
defer func() {
if r := recover(); r != nil {
fmt.Println("Recovered div panic", r)
}
}()
cgoPanic(&wg)
}()
wg.Wait()
}