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

Crash due to missing Cython exception handling for relational_to_bool() #14211

Closed
orlitzky opened this issue Mar 1, 2013 · 30 comments
Closed

Comments

@orlitzky
Copy link
Contributor

orlitzky commented Mar 1, 2013

sage: f(x)=matrix()                           
sage: bool(f(x)==f(x))

terminate called after throwing an instance of 'std::runtime_error'
  what():  Number_T::hash() python function (__hash__) raised exception
------------------------------------------------------------------------
Unhandled SIGABRT: An abort() occurred in Sage.
This probably occurred because a *compiled* component of Sage has a bug
in it and is not properly wrapped with sig_on(), sig_off().
Sage will now terminate.
------------------------------------------------------------------------

Component: symbolics

Issue created by migration from https://trac.sagemath.org/ticket/14211

@orlitzky orlitzky added this to the sage-5.11 milestone Mar 1, 2013
@jdemeyer jdemeyer modified the milestones: sage-5.11, sage-5.12 Aug 13, 2013
@sagetrac-vbraun-spam sagetrac-vbraun-spam mannequin modified the milestones: sage-6.1, sage-6.2 Jan 30, 2014
@sagetrac-vbraun-spam sagetrac-vbraun-spam mannequin modified the milestones: sage-6.2, sage-6.3 May 6, 2014
@sagetrac-vbraun-spam sagetrac-vbraun-spam mannequin modified the milestones: sage-6.3, sage-6.4 Aug 10, 2014
@jdemeyer

This comment has been minimized.

@jdemeyer jdemeyer modified the milestones: sage-6.4, sage-6.5 Jan 31, 2015
@rwst
Copy link

rwst commented May 3, 2015

Upstream: Reported upstream. Developers acknowledge bug.

@rwst
Copy link

rwst commented May 3, 2015

comment:7

Reported as pynac/pynac#34

@rwst rwst modified the milestones: sage-6.5, sage-6.7 May 3, 2015
@rwst
Copy link

rwst commented May 3, 2015

comment:8

Minimal case given. In Sage hash(matrix()) will not allow hashing probably because PyObject_Hash will fail and to prevent that. The fail happens in Pynac nevertheless because the check is avoided due to function expansion and there leads to the crash.

One part of the fix is preventing Sage from crashing. Surrounding the call to Pynac in Expression::__nonzero__ with guards:

            sig_on()
            pynac_result = relational_to_bool(self._gobj)
            sig_off()

leads to:

sage: bool(f(x)==f(x))
terminate called after throwing an instance of 'std::runtime_error'
  what():  Number_T::hash() python function (__hash__) raised exception
---------------------------------------------------------------------------
TypeError: mutable matrices are unhashable

which is the same you get with hash(matrix()), so quite sensible. What more? Why are matrices generated by vector*vector (the original case) or those in a function definition (like above) mutable at all?

@rwst

This comment has been minimized.

@rwst
Copy link

rwst commented May 3, 2015

Changed upstream from Reported upstream. Developers acknowledge bug. to Reported upstream. Developers deny it's a bug.

@rwst rwst changed the title Crash in GiNaC::Number_T::hash() Crash due to missing sig_on in Expresion.__nonzero__ May 3, 2015
@rwst rwst changed the title Crash due to missing sig_on in Expresion.__nonzero__ Crash due to missing sig_on in Expression.__nonzero__ May 3, 2015
@nbruin
Copy link
Contributor

nbruin commented May 3, 2015

comment:11

Replying to @rwst:

which is the same you get with hash(matrix()), so quite sensible. What more? Why are matrices generated by vector*vector (the original case) or those in a function definition (like above) mutable at all?

Because the default for matrix creation is to create a mutable matrix. That's because a mutable matrix can be turned into an immutable one, but not the other way around (that requires copying the matrix to a new, mutable, one). That default is probably inconvenient for symbolics.

Are you sure this is the sole problem, though? If we try this:

def imm_mt(*args,**kwargs):
    M=matrix(*args,**kwargs)
    M.set_immutable()
    return M
f(x)=imm_mt()

then we get

sage: hash(f(x))
0

but bool(f(x)==f(x)) still crashes. is it trying to see if f(x)*f(x)^(-1) is one?

@rwst
Copy link

rwst commented May 4, 2015

comment:12

Replying to @nbruin:

Are you sure this is the sole problem, though?

I have reopened the Pynac issue. The crash is in exactly the same call tree. It happens while trying to multiply the rhs with -1 to get lhs-rhs. So:

sage: f(x)=matrix()
sage: bool(f(x)==1)
True
sage: bool(1==f(x))
<crash>

Also no, I don't think it's the sole problem. Either Sage or Pynac will have to check somewhere before evaluating that all mutable Python objects of the expression are switched to immutable (or make immutable copies).

EDIT: But that would be a different ticket: #18360

@jdemeyer
Copy link

jdemeyer commented May 4, 2015

@rwst
Copy link

rwst commented May 4, 2015

Commit: b9698e0

@rwst
Copy link

rwst commented May 4, 2015

comment:17

Replying to @nbruin:

If we try this:

def imm_mt(*args,**kwargs):
    M=matrix(*args,**kwargs)
    M.set_immutable()
    return M
f(x)=imm_mt()

then we get

sage: hash(f(x))
0

but bool(f(x)==f(x)) still crashes.

My best guess at the moment is that somewhere in between a copy is made which, as you suggested, is then mutable again. This can only be fixed by a dedicated ticket such as #18360.

As to this code, the reviewer should check doubly if what I did here was right. There was not a single example in Sage with a special function catching exceptions from which I could have learned.


New commits:

b9698e014211: catch exceptions from Expression.__nonzero__

@jdemeyer
Copy link

jdemeyer commented May 4, 2015

comment:18

Obviously, a doctest is needed.

Besides that, it makes no sense to add an additional layer _nonzero_. The exception should be handled in the pynac interface, i.e. the relational_to_bool() function.

@rwst
Copy link

rwst commented May 5, 2015

@rwst
Copy link

rwst commented May 5, 2015

comment:20

Interesting. The C++ layer outputs an error message, and the Python layer deals with the error too, because presumably the error from calling PyHash from the C++ layer is still pending.


New commits:

e1374da14211: catch Pynac exceptions

@rwst
Copy link

rwst commented May 5, 2015

Changed commit from b9698e0 to e1374da

@jdemeyer
Copy link

jdemeyer commented May 5, 2015

comment:21

Replying to @rwst:

Interesting. The C++ layer outputs an error message, and the Python layer deals with the error too, because presumably the error from calling PyHash from the C++ layer is still pending.

Well, behaviour shouldn't depend on what "presumably" happens (does the traceback look sensible? If not, you're certainly doing it wrong). I admit I don't know the proper way to deal with this (a C++ exception and PyErr_Occurred() != NULL), but it's not right like this.

Besides that, I would never print the C++ exception.

@jdemeyer
Copy link

jdemeyer commented May 5, 2015

comment:23

I can have a look at how to properly deal with this, but not now.

@rwst
Copy link

rwst commented Jun 17, 2015

Changed commit from e1374da to none

@rwst
Copy link

rwst commented Jun 17, 2015

Changed author from Ralf Stephan to none

@rwst
Copy link

rwst commented Jun 17, 2015

Changed branch from u/rws/14211 to none

@rwst
Copy link

rwst commented Jun 17, 2015

comment:24

Now that the actual bug is fixed in future Pynac (#18360) the given doctest will not work in the future, so I removed the commit.

@rwst
Copy link

rwst commented Jun 22, 2015

comment:25

Branch reset because other exceptions can be thrown.


New commits:

e1374da14211: catch Pynac exceptions

@rwst
Copy link

rwst commented Jun 22, 2015

Commit: e1374da

@rwst
Copy link

rwst commented Jun 22, 2015

Branch: u/rws/14211

@rwst
Copy link

rwst commented Oct 19, 2015

Changed commit from e1374da to none

@rwst
Copy link

rwst commented Oct 19, 2015

Changed branch from u/rws/14211 to none

@rwst
Copy link

rwst commented Oct 19, 2015

comment:26

No longer necessary (doctest added in #18360)

@rwst rwst removed this from the sage-6.7 milestone Oct 19, 2015
@vbraun vbraun closed this as completed Oct 22, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants