Handling panic in C code(CGo)

1,527 views
Skip to first unread message

vaish...@ptechnosoft.com

unread,
Apr 21, 2016, 10:37:55 AM4/21/16
to golang-nuts
package main

/*
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


sri...@laddoo.net

unread,
Apr 21, 2016, 3:59:45 PM4/21/16
to golang-nuts
The panic is happening in a different goroutine from where you're calling recover.

If do you the following it'll work as expected:

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()
}

James Bardin

unread,
Apr 22, 2016, 6:03:59 PM4/22/16
to golang-nuts

"fatal error:" isn't a panic you can catch. The runtime is aborting because there was a fault while running C code.
Reply all
Reply to author
Forward
0 new messages