-
-
Notifications
You must be signed in to change notification settings - Fork 115
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Not catching panics across FFI boundaries #74
Comments
Abort seems the best, yes. |
Or wait until the compiler does this abort for us? I think that’s the expected eventual resolution of rust-lang/rust#58794 (though with an opt-out that I’m not sure is implemented yet.) |
Personally I'd wait for the compiler, I don't want to change everything back yet another time only to revert the change again in a bit. |
Made this issue a bit more generic. This applies to all gtk-rs code currently. |
Are there news about if the compiler implement it or not yet? |
There's a whole WG about that: https://rust-lang.github.io/rfcs/2797-project-ffi-unwind.html / https://github.com/rust-lang/project-ffi-unwind . It's not finished yet. |
Thanks for the information @sdroege 🤗 |
The status quo is that unwinding across FFI is Undefined Behavior. Therefore all callbacks called from C should be wrapped into something that uses Only if and when that WG propose languages changes that end up implemented, maybe that wrapping will become unnecessary. |
@SimonSapin I found rust-lang/rust#58794 is closed and in rust-lang/rust#58760 link to rust-lang/rust#55982 merged PR. Is that also UB when the FFI is Rust function to be used from C or that fix the UB? (even if it's in nightly only yet and it is not unwind but at least is not undefined, it will abort). And thanks about the information about FFI and unwind. |
Currently any unwinding across For example this adds support for an |
@sdroege this should be moved to gtk-rs-core |
I don't understand one thing in here: the initial issue description is specifically about Cairo "user data". But doesn't the problem also apply in any signal callbacks? I've already panicked in my code more than once and it's never blown up badly, so was it just by luck? |
Yes, it's about any callbacks that go through FFI. |
So if I'm getting a stack trace like
then that's totally not guaranteed to work in the general case? If I understand the linked threads above correctly, then this ought to work in a defined matter some time in the future. Nevertheless, I'd argue for running signal callbacks in a How do other language bindings handle exceptions? |
Something like that existed in gtk-rs for a long time. Then Rust changed to make it defined behaviour (directly abort the process) and we removed it. Then this change was reverted again and we reverted the removal. Then Rust again made it defined behaviour and we removed the gtk-rs code. And again it was reverted and promised to be added again in the near future. And here we are now :) It seems like it's really close (I hope for real) now and actually works like that in nightly already if I understand correctly. The behaviour in any case would be to kill the process because that's the only thing you can safely do in such situations.
Unwinding across language boundaries is generally a bad idea and I'm not aware of any language binding where that is handled in any other way than UB or killing the process. |
There are some updates in rust-lang/rust#86155 (comment) . It looks like this is finally going to be solved in Rust in the foreseeable future. |
|
That's not sufficient. What we need is that the With |
With 1.81 this should be solved finally: rust-lang/rust#116088 |
gtk-rs/cairo#257 added bindings for “user data” owned by cairo objects. Each user data entry has a destructor function pointer that cairo calls when the object is destroyed. This helps solve life time issues, since with reference counting it can be hard to predict when an object will be destroyed exactly.
The bindings are generic and accept user data of any type. They forward destructor function pointer calls to
Drop
, which potentially panic and unwind. However, until rust-lang/rust#58794 is resolved, unwinding into C is undefined behavior.A possible fix is using
std::panic::catch_unwind
in the destructor function. However even if we stash the panic payload somewhere at that point, there is no good place in the code to callresume_unwind
. So the best we can do might be to abort the process.The text was updated successfully, but these errors were encountered: