Skip to content
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

Properly report exceptions thrown during module initialization. #1362

Merged
merged 1 commit into from
Jun 15, 2018
Merged

Properly report exceptions thrown during module initialization. #1362

merged 1 commit into from
Jun 15, 2018

Conversation

anntzer
Copy link
Contributor

@anntzer anntzer commented Apr 17, 2018

If an exception is thrown during module initialization, the
error_already_set destructor will try to call get_internals() after
setting Python's error indicator, resulting in a SystemError: ... returned with an error set.

Fix that by temporarily stashing away the error indicator when
initializing the internals.

(I think any proper unit test would require creating a new module just for that purpose, and I'm not particularly familiar with the testing machinery used by pybind, so guidance would be welcome here. But "it works for me"...)

xref #1113.

@anntzer
Copy link
Contributor Author

anntzer commented May 5, 2018

Kindly bumping.

@jagerman
Copy link
Member

I'm having trouble reproducing the error; do you have a simple example code that fails?

@jagerman
Copy link
Member

Oops, never mind, I see you gave one in the referenced issue.

@jagerman
Copy link
Member

I think the error_scope fix here is good, but is in the wrong place--it should instead, I think, be backed up one level, into the error_already_set destructor rather than get_internals. That is, adding the error scope here instead:

error_already_set::~error_already_set() {
    if (type) {
        error_scope scope;
        gil_scoped_acquire gil;
        type.release().dec_ref();
        value.release().dec_ref();
        trace.release().dec_ref();
    }
}

It works with your example in #1113; do you want to test it out some more (and update the PR if it all checks out)?

If an exception is thrown during module initialization, the
error_already_set destructor will try to call `get_internals()` *after*
setting Python's error indicator, resulting in a `SystemError: ...
returned with an error set`.

Fix that by temporarily stashing away the error indicator in the
destructor.
@anntzer
Copy link
Contributor Author

anntzer commented May 25, 2018

It's not totally clear to me why it'd make more sense to stash it in this scope instead, but sure, it works. Force-pushed the fix as suggested.

@jagerman
Copy link
Member

It's not totally clear to me why it'd make more sense to stash it in this scope instead, but sure, it works. Force-pushed the fix as suggested.

Well, it seems to me that the issue here isn't that get_internals() is doing something wrong, but rather that error_already_set is setting an error but then making a call that can lead to Python code (via internals).

@anntzer
Copy link
Contributor Author

anntzer commented Jun 13, 2018

Kindly bumping again (comments addressed).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants