Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Properly report exceptions thrown during module initialization. - #1362

Merged
jagerman merged 1 commit into
pybind:masterfrom
anntzer:exception-in-module-init
Jun 15, 2018
Merged

Properly report exceptions thrown during module initialization.#1362
jagerman merged 1 commit into
pybind:masterfrom
anntzer:exception-in-module-init

Conversation

@anntzer

@anntzer anntzer commented Apr 17, 2018

Copy link
Copy Markdown
Contributor

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

anntzer commented May 5, 2018

Copy link
Copy Markdown
Contributor Author

Kindly bumping.

@jagerman

Copy link
Copy Markdown
Member

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

@jagerman

Copy link
Copy Markdown
Member

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

@jagerman

Copy link
Copy Markdown
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

anntzer commented May 25, 2018

Copy link
Copy Markdown
Contributor Author

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
Copy Markdown
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

anntzer commented Jun 13, 2018

Copy link
Copy Markdown
Contributor Author

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.

2 participants