-
Notifications
You must be signed in to change notification settings - Fork 286
Panics through FFI in error callbacks #228
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
Comments
Lol wow, I dunno how we didn't see this. I think we may have done this in an attempt to get away from libc As for printing, we can just use Another alternative is to not abort the process, just return zero from the callback. This will result in failure being returned from the underlying C function, and the user will either see a Rust error or a |
I honestly have no idea .
We can't do that without
Hmm I did not think of that, are we sure this is also correct usage for the error callback?
https://github.com/bitcoin-core/secp256k1/blob/master/include/secp256k1.h#L288 |
I don't think so, upstream assumes the callbacks will never return. I think @elichai is right. The point of the callbacks is that they never return because this would mean continuing parts of the program. |
Every single |
I had incorrect understanding that callback functions can return. It makes sense that error callback should not return, because everything can happen, but it seems to me that returning from invalid callback should be OK, because it is about incorrect parameters, and supplying incorrect parameters is much more probable event than some fatal problems where error callback is called, and incorrect parameters is not a situation where just duying is what programmer would expect. Or is the abort on illegal parameters has the role of an insurance against people not checking results returned from the functions ? |
Ok you had I think the error callback must crash, what cleaner thing can you do if you reached a assumed-to-be-impossible state? And upstream says for the illegal argument callback:
https://github.com/bitcoin-core/secp256k1/blob/master/include/secp256k1.h#L242 If we pass the user a Rust errors instead, we violate this philosophy. edit: Okay, yeah, if we guarantee that we never hit a Note, there's even |
cc #288. @real-or-random I don't understand your objection. We have unit tests for every single instance of I think we should just do nothing in the callbacks, and then trust that an assertion failure will fire later on. You cannot hit these assertions without unsafe code anyway. The current situation, which is UB, is not tenable. |
Indeed, I don't claim I have a solution, it's just fucked up.
I agree. Even though a segfault is a nice way of aborting, too. :P But we shouldn't rely on this... |
As Elichai has noted elsewhere, I am mistaken and this is not actually UB. In recent version of rustc it will reliably trigger an abort and (empirically) in older rustcs it seems to "just work". |
Panicking from C is not UB in newer rust versions and will reliably trigger an abort (without unwinding). In older rust versions, it is technically UB but empirically it seems to "just work" (and what should it realistically do except crashing, which is what we intent). Since there's potentially no unwinding, we can't test this behavior using [should_panic]. This PR will check the exit code instead in our CI tests. Fixes rust-bitcoin#228.
Panicking from C is not UB in newer rust versions and will reliably trigger an abort (without unwinding). In older rust versions, it is technically UB but empirically it seems to "just work" (and what should it realistically do except crashing, which is what we intent). Since there's potentially no unwinding, we can't test this behavior using [should_panic]. This PR will instead check the libtest output explicitly in our CI tests. Fixes rust-bitcoin#228.
Panicking from C is not UB in newer rust versions and will reliably trigger an abort (without unwinding). In older rust versions, it is technically UB but empirically it seems to "just work" (and what should it realistically do except crashing, which is what we intent). Since there's potentially no unwinding, we can't test this behavior using [should_panic]. This PR will instead check the libtest output explicitly in our CI tests. Fixes rust-bitcoin#228.
Panicking from C is not UB in newer rust versions and will reliably trigger an abort (without unwinding). In older rust versions, it is technically UB but empirically it seems to "just work" (and what should it realistically do except crashing, which is what we intent). Since there's potentially no unwinding, we can't test this behavior using [should_panic]. This PR will instead check the libtest output explicitly in our CI tests. Fixes rust-bitcoin#228.
Panicking from C is not UB in newer rust versions and will reliably trigger an abort (without unwinding). In older rust versions, it is technically UB but empirically it seems to "just work" (and what should it realistically do except crashing, which is what we intent). Since there's potentially no unwinding, we can't test this behavior using [should_panic]. This PR will instead check the libtest output explicitly in our CI tests. Fixes rust-bitcoin#228.
Panicking from C is not UB in newer rust versions and will reliably trigger an abort (without unwinding). In older rust versions, it is technically UB but empirically it seems to "just work" (and what should it realistically do except crashing, which is what we intent). Since there's potentially no unwinding, we can't test this behavior using [should_panic]. This PR will instead check the libtest output explicitly in our CI tests. Fixes rust-bitcoin#228.
Panicking from C is not UB in newer rust versions and will reliably trigger an abort (without unwinding). In older rust versions, it is technically UB but empirically it seems to "just work" (and what should it realistically do except crashing, which is what we intent). Since there's potentially no unwinding, we can't test this behavior using [should_panic]. This PR will instead check the libtest output explicitly in our CI tests. Fixes rust-bitcoin#228.
Panicking from C is not UB in newer rust versions and will reliably trigger an abort (without unwinding). In older rust versions, it is technically UB but empirically it seems to "just work" (and what should it realistically do except crashing, which is what we intent). Since there's potentially no unwinding, we can't test this behavior using [should_panic]. This PR will instead check the libtest output explicitly in our CI tests. Fixes rust-bitcoin#228.
Right now we override the error callbacks at compile time with:
rust-secp256k1/secp256k1-sys/src/lib.rs
Lines 364 to 369 in c6ab14b
rust-secp256k1/secp256k1-sys/src/lib.rs
Lines 387 to 392 in c6ab14b
But this is sadly UB if the panic strategy is
unwind
(the default):rust-lang/rust#52652
Now the easiest solution is to replace the panic with abort, but then we have a few problems:
Aborted (core dumped)
orIllegal instruction (core dumped)
which makes it very hard to pinpoint (We could conditionally print ifstd
is on, but that sucks).abort
do we call?2.a. The libc one?(adds the assumption of libc which might break for wasm).
2.b. The intrinsic one? (requires nightly).
2.c.
std::process::abort
? requires libstd.2.d. Stabilize
intrinsics::abort
incore
rust-lang/rfcs#2512Another potential solutions:
panic=abort
(imo this isn't a good solution).std::panic::catch_unwind
which will catch the panic ifstd
is on but will still print the output and/or stacktrace."C unwind"
which allows unwinding the stack through C. (https://github.com/rust-lang/project-ffi-unwind/blob/master/rfcs/0000-c-unwind-abi.md)#[cfg(panic = '...')]
rust-lang/rust#74754 which allows to condition on ifpanic=abort
or not.panic
and see if we can still trigger printing but abort instead, probably won't be possible in stable.abort!(...)
), but even if they'll get accepted we won't use that release for a long time.(Thanks to @joshtriplett for some of the suggestions)
The text was updated successfully, but these errors were encountered: