-
Notifications
You must be signed in to change notification settings - Fork 2.2k
fix: subinterpreter exception handling SEGFAULT #5795
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
Conversation
@b-pass could you please help reviewing this PR? |
That was the intent, yes.
The need to prevent allowing |
@b-pass I've updated the PR to remove all in-flight exception handling instead. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good to me
Thanks @b-pass ! @justend29 Could you please review and maybe revise the PR description? (The Changes section seem to be out of date?) |
@henryiii I'm thinking the CIBW / iOS wheel macos-latest failure is unrelated. WDYT? |
Yes, see pypa/cibuildwheel#2556 (comment) |
Thanks @henryiii for confirming! |
@rwgk Done. Thanks for the diligence. |
Description
pybind11 version: b67d07e
The destructor of
subinterpreter_scoped_activate
tests forstd::uncaught_exceptions
to throwstd::current_exception
. These are two independent states that are unrelated to each other. As such, the destructor can easily SEGFAULT when throwing anullptr
fromstd::current_exception()
. The following example causes a SEGFAULT onstd::rethrow_exception
, hereExplaining the issue:
The
subinterpreter_scoped_activate
insidescoped_subinterpreter
is being destroyed from stack unwinding. Therefore,std::uncaught_exceptions
is 1, since this merely counts the number of in-flight exceptions. The current destructor would consequently try to throwstd::current_exception()
. However,std::current_exception()
returnsnullptr
, as the destructor is not called from a catch block, wherestd::current_exception()
returns the currently handled exception of the enclosing catch block - for which there is none.Changes
The original code intends to halt stack unwinding of any in-flight exception that happens to be a
py::error_already_set
,mitigating the user error of letting
error_already_set
exceptions escape an active subinterpreter. As halting stack unwinding without a surroundingtry-catch
is not possible, the invalid checks were removed.Suggested changelog entry: