Catch/handle cgo SIGSEGV

1,124 views
Skip to first unread message

Tamás Gulácsi

unread,
Sep 17, 2020, 11:51:53 AM9/17/20
to golang-nuts

I'm searching for help in https://github.com/godror/godror/issues/100 - I've added a recover, called debug.SetPanicOnFault, without success: the extra free still panics with SIGSEGV, and the recover does not catch it (or I coded it wrongly): https://github.com/godror/godror/blob/2dab250ab19e158ba97699841f40c9de9d061f29/stmt.go#L306


Thanks!

Ian Lance Taylor

unread,
Sep 17, 2020, 3:00:52 PM9/17/20
to Tamás Gulácsi, golang-nuts
On Thu, Sep 17, 2020 at 8:52 AM Tamás Gulácsi <tgula...@gmail.com> wrote:
>
> I'm searching for help in https://github.com/godror/godror/issues/100 - I've added a recover, called debug.SetPanicOnFault, without success: the extra free still panics with SIGSEGV, and the recover does not catch it (or I coded it wrongly): https://github.com/godror/godror/blob/2dab250ab19e158ba97699841f40c9de9d061f29/stmt.go#L306
>
> panic: https://github.com/godror/godror/issues/100#issuecomment-694192603

When a SIGSEGV occurs while running C code called via cgo, that
SIGSEGV is not turned into a Go panic.

It works this way both because 1) C is not a memory-safe language, and
if the C code has not installed a signal handler there is no reason to
think that the C code is prepared to carry on after a segmentation
violation; 2) the mechanism that Go uses to turn a memory error into a
panic can only work for Go code, not for C code.

Ian

Tamás Gulácsi

unread,
Sep 17, 2020, 3:08:38 PM9/17/20
to golang-nuts
Thanks, absolutely logical.

Can you provide some skim of a C-side signal handler that could induce a Go panic?
All I want is to have an error on Go side, instead of a crash (though it may be safer to have a crash...).

Brian Candler

unread,
Sep 17, 2020, 3:38:33 PM9/17/20
to golang-nuts
It's very hard to think of a case where a SIGSEGV in a C program could continue safely.  It typically means pointer access out of bounds, which in turn is usually because some data structure has become corrupted.

My question is, where is this SEGV coming from?  Is this a bug in the Oracle libraries?  If so, you most likely want to find a way to work around that bug, to prevent the SEGV occurring in the first place.  Does this SEGV occur when running a native C program which calls the ORA libraries in the same way?  If not, why not?  Could it be a threading issue, perhaps?

Failing that, the only safe solution I can think of is to fork a child, run the Oracle client in the child, and communicate with the child over a socket (e.g. with gRPC). This would have the nice side-effect that the parent could be built without CGO; and if the child crashes, you can just fork and exec another one.

Ian Lance Taylor

unread,
Sep 17, 2020, 4:11:18 PM9/17/20
to Tamás Gulácsi, golang-nuts
On Thu, Sep 17, 2020 at 12:09 PM Tamás Gulácsi <tgula...@gmail.com> wrote:
>
> Can you provide some skim of a C-side signal handler that could induce a Go panic?
> All I want is to have an error on Go side, instead of a crash (though it may be safer to have a crash...).

I can't think of any safe way that a C signal handler could cause a
panic in the goroutine that called the C code that made the invalid
memory reference.

You could in principle have a C signal handler call a Go function that
sends a message on a buffered channel that tells some other goroutine
to panic. I think that could be safe. But it would not be safe for a
C signal handler to call a Go function that calls panic. That would
leave the program with most signals blocked.

Ian




> Ian Lance Taylor a következőt írta (2020. szeptember 17., csütörtök, 21:00:52 UTC+2):
>>
>> On Thu, Sep 17, 2020 at 8:52 AM Tamás Gulácsi <tgula...@gmail.com> wrote:
>> >
>> > I'm searching for help in https://github.com/godror/godror/issues/100 - I've added a recover, called debug.SetPanicOnFault, without success: the extra free still panics with SIGSEGV, and the recover does not catch it (or I coded it wrongly): https://github.com/godror/godror/blob/2dab250ab19e158ba97699841f40c9de9d061f29/stmt.go#L306
>> >
>> > panic: https://github.com/godror/godror/issues/100#issuecomment-694192603
>>
>> When a SIGSEGV occurs while running C code called via cgo, that
>> SIGSEGV is not turned into a Go panic.
>>
>> It works this way both because 1) C is not a memory-safe language, and
>> if the C code has not installed a signal handler there is no reason to
>> think that the C code is prepared to carry on after a segmentation
>> violation; 2) the mechanism that Go uses to turn a memory error into a
>> panic can only work for Go code, not for C code.
>>
>> Ian
>
> --
> You received this message because you are subscribed to the Google Groups "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.
> To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/30ca05ec-255b-4d67-b45f-89fde5396bb6n%40googlegroups.com.

Tamás Gulácsi

unread,
Sep 18, 2020, 4:13:44 AM9/18/20
to golang-nuts
Thank you very much!
It's way more complicated than I'd to deal with, so I'll leave it as is: crash the program if the C side gots a SIGSEGV.
Even the gRPC child seems more managable.
Reply all
Reply to author
Forward
0 new messages