Search code examples
rustcgo

Analyzing a crash from a rust-generated C library


I needed to call Rust code from my Go code. Then I used C as my interface. I did this:

I've created a Rust library that takes a CStr as a parameter, and returns a new processed string back as CStr. This code is statically compiled to a static C library my_lib.a.
Then, this library is statically linked with my Go code, that then calls the library API using CGo (Go's representation to C String, just like Rusts's Cstr).

The final Go binary is sitting inside a docker container in my kubernetes. Now, my problem is that is some cases where the library's API is called, my pod (container) is crashing. Due to the nature of using CStr and his friends, I must use unsafe scopes in some places, and I highly suspect a segfault that is caused by one of the ptrs used in my code, but I have no way of communicating the error back to the Go code that could be then printed OR alternatively get some sort of a core dump from Rust/C so I can point out the problematic code. The pod just crashes with no info whatsoever, at least to my knowledge..

So my question is, how can I:

  1. Recover from panic/crashes that happen inside an unsafe code? or maybe wrap it with a recoverable safe scope?
  2. Override the SIG handlers so I can at least "catch" the errors and not crash? So I can debug it.
  3. Perhaps communicate a signal interruption that was caused in my c-lib that was generated off Rust back to the caller?

I realize that once Rust is compiled to a c-library, it is a matter of C, but I have no idea how to tackle this one.

Thanks!


Solution

  • I've created a Rust library that takes a CStr as a parameter, and returns a new processed string back as CStr.

    Neither operation seems OK:

    • the CStr documentation specifically notes that CStr is not repr(C)
    • CStr is a borrowed string, a "new processed string" would have to be owned (so a CString, which also isn't repr(C)).

    Due to the nature of using CStr and his friends, I must use unsafe scopes in some places, and I highly suspect a segfault that is caused by one of the ptrs used in my code, but I have no way of communicating the error back to the Go code that could be then printed OR alternatively get some sort of a core dump from Rust/C so I can point out the problematic code. [...] Recover from panic/crashes that happen inside an unsafe code? or maybe wrap it with a recoverable safe scope?

    If you're segfaulting there's no panic or crash which Rust can catch or manipulate in any way. A segfault means the OS itself makes your program go away. However you should have a core dump the usual way, this might be a configuration issue with your container thing.

    Override the SIG handlers so I can at least "catch" the errors and not crash? So I can debug it.

    You can certainly try to handle SIGSEGV, but after a SIGSEGV I'd expect the program state to be completely hosed, this is not an innocuous signal.