How does one prevent a Rust program from crashing when a C lib function causes a crash?
there's nothing you can do about something that is out of the scope of rust.
if you cannot avoid such buggy C code, only thing to prevent your main program from crashing is to create a separate process for the ffi functionality, and use RPC from to call it.
Even if you could "catch" the crash in Rust code, how would you know it is safe to continue? Best to let it crash.
You need to run the crashy code in a separate process. You could launch a C program from a separate executable using std's Command
and then use some kind of IPC (inter-process communication) to control it.
To have a single self-contained executable, you could also include both Rust and C in the same binary, but fork()
the process, and run each language one side of the fork. However, fork()
itself is a very dangerous function that could make things even more crashy, so it needs care (e.g. fork()
before your program does anything non-trivial).
Yet another option is to compile the C code to WASM. Then you can execute WASM with an interpreter that will catch and contain crashes. An advanced version of this is rlbox that converts C -> WASM -> C to get C code that will catch its own crashes.
converts C -> WASM -> C to get C code that will catch its own crashes
Wild. Thanks for all the ideas!
Under Windows I had the second program stored as a resource of the first. Extracting the second to TEMP then running it from there is fairly easy.
I've also appended the second to the end of the first. The annoyance is locating the end of the first / start of the second.
I assume something similar is possible for other operating systems. Most (maybe all) loaders don't care what's past the defined image.
Thank you for sharing.
This is nearly trivial in Rust with include_bytes!(), though it does have the rather horrifying internal mechanism of splatting a few hundred megabytes or whatever of an escaped binary string into the parsed code (after macro expansion)
The main trouble is convincing cargo to build things in the right order so you include an updated binary and getting the path to it; the xtask pattern is handy for that.
I'm worried that this can look like malware that is unpacking its hidden payload. I already get reports that my well-behaved programs get blocked by antivirus programs from time to time.
Under Windows you can use SEH exception handlers to catch invalid memory accesses.
You would need to wrap all of the crashing functions in C, then link those wrappers to your Rust code.
While this works, I do not recommend using this, unless you know exactly which issues in C library are causing the crashes to happen and how.