Loading...
ffi-unwind 2020-01-13
scenarios
what kinds of things
can
be propagated
panics
foreign exceptions
“forced unwinds”
these are meant to be
“invisible”
to the language, language users aren’t really meant to interact with them
C++ lets you catch them but perhaps it shouldn’t
arise from longjmp in MSVC
arise from
pthread_exit
in some pthread implementations
(GNU
C but not MUSL)
in glibc, this will unwind the stack to the root of the thread
in MUSL, pthread exit just frees the stack immediately, Rust cannot handle this
maybe arise from various C functions due to
pthread_cancel
C++
(or
other language, perhaps) exceptions
“painless subset”
catching panics
propagating foreign exceptions across frames without destructors
core requirement of Rust
it has to be UB to unwind a Rust frame w/o executing a destructor within
C++
presumably
calls this UB too? not entirely clear
tricky problems
under panic=abort:
do we want to enable longjmp with
-Cpanic=abort
(across
frames that have no destructors)?
if you do, then you can’t locally detect foreign unwinding at the
“C/unwind”
call site
possible solutions
Option 1:
“2
APIs, always permit forced unwinding”
introduce C and C unwind
the
“
C
”
ABI:
it is UB to unwind, except for a forced
unwind
without a destructor in scope, regardless of
-Cpanic=unwind
or
-Cpanic=abort
this allows us to abort in
extern
"
C
"
fn()
if we so choose, except for forced
unwinding
, we could also abort at call sites in debug builds
also, this means you can use longjmp with
“C”
ABI, so long as you know there are no destructors in scope
the
“C
unwind” ABI:
-Cpanic=unwind
a Rust panic is defined behavior
it is UB for a forced
unwinding
or longjmp if there are destructors in scope
(but on some platforms it may execute destructors)
other foreign exceptions are defined behavior
(?)
-Cpanic=abort
Rust panics will abort and will not propagate
add a shim that
permits forced
unwinding
to propagate
but aborts otherwise
Pros:
if you are working with C++, you start to get aborts instead of exceptions
we can use
“C”
ABI for read, so long as you won’t run dtors
Cpanic=abort cannot introduce UB
minimal overhead for shims because
“C
unwind” is unusual
Cons:
but
pthread_cancel
cannot be combined with destructors
unless we say that it’s not UB if you are on the right platforms and have panic=unwind
(but
then panic=abort introduces UB in that case)
Option 1b:
as above, except that
“C
unwind” treats all foreign exceptions the same
Please turn on JavaScript to use Paper in all of its awesomeness. ^_^
scenarios
Option 1b: