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

Exceptions sometimes lead to "terminate called" #13

Open
saraedum opened this issue Sep 20, 2021 · 1 comment
Open

Exceptions sometimes lead to "terminate called" #13

saraedum opened this issue Sep 20, 2021 · 1 comment

Comments

@saraedum
Copy link
Contributor

saraedum commented Sep 20, 2021

When running the following code snippet, a C++ exception is correctly reported in an interactive Python session:

>>> from pyintervalxt import IntervalExchangeTransformation
>>> iet = IntervalExchangeTransformation((18, 3), (1, 0))
>>> iet
[a: 18] [b: 3] / [b] [a]
>>> from pyeantic import eantic
>>> L = eantic.renf("a^3 - a^2 - a - 1", "a", "[1.84 +/- 0.01]")
>>> lengths = [L.gen(), eantic.renf_elem(L, "-3*a^2 + 2*a - 1")]
>>> IntervalExchangeTransformation(lengths, [1, 0])
---------------------------------------------------------------------------
TypeError: none of the 4 overloaded methods succeeded. Full details:
  Lengths<std::vector<eantic::renf_elem_class> >::Lengths<std::vector<eantic::renf_elem_class> >(intervalxt::cppyy::Lengths<std::vector<eantic::renf_elem_class> >&&) =>
    ValueError: could not convert argument 1 (object is not an rvalue)
  Lengths<std::vector<eantic::renf_elem_class> >::Lengths<std::vector<eantic::renf_elem_class> >(const intervalxt::cppyy::Lengths<std::vector<eantic::renf_elem_class> >&) =>
    TypeError: could not convert argument 1
  Lengths<std::vector<eantic::renf_elem_class> >::Lengths<std::vector<eantic::renf_elem_class> >(const std::vector<eantic::renf_elem_class>&) =>
    invalid_argument: all lengths must be non-negative
  Lengths<std::vector<eantic::renf_elem_class> >::Lengths<std::vector<eantic::renf_elem_class> >() =>
    TypeError: takes at most 0 arguments (1 given)

However, later in the same session, the same invocation causes a crash:

>>> iet = IntervalExchangeTransformation((18, 3), (1, 0))
>>> from pickle import loads, dumps
>>> loads(dumps(iet))
[a: 18] [b: 3] / [b] [a]
>>> lengths = [L.gen(), eantic.renf_elem(L, "-3*a^2 + 2*a - 1")]
>>> IntervalExchangeTransformation(lengths, [1, 0])
terminate called after throwing an instance of 'std::invalid_argument'
  what():  all lengths must be non-negative

Since the same exception was apparently thrown, I don't understand why the loads and dumps on an unrelated object, made it so that this time the exception could not be caught and handed over to Python.

Unfortunately, I could not find a short reproducer for this yet. I can reproduce the above on Linux in the following conda environment:

conda create -n terminate -c flatsurf pyintervalxt pyeantic
conda activate terminate
python
saraedum added a commit to saraedum/intervalxt that referenced this issue Sep 20, 2021
and report test cases that lead to a terminate due to wlav/cppyy#13
@wlav
Copy link
Owner

wlav commented Sep 20, 2021

I'll have a look, but all method calls into C++ have a catch (...), so the only reason I can think of, is that the C++ exception has two type_info's. Nominally, the easiest way to "achieve" that is to have one JIT-ed and one linked, but a) I haven't seen that to be a problem on Linux; b) a standard exception is a weird one for this to happen to; and c) I don't see where this JIT-ing would occur. So, I'm a bit at a loss as to how this can occur ...

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

No branches or pull requests

2 participants