Open vbraun opened 7 years ago
Replying to @vbraun:
Python will then ignore it.
There is nothing that cysignals
can do about that. I consider it a Python bug: if __del__
can't handle exceptions, it shouldn't check for signals either. See https://bugs.python.org/issue31388
I don't see a solution without patching Python somehow.
It would be convenient if Python somehow had a hook to deal with unraisable exceptions. But it doesn't: it just deletes the exception and there is (AFAIK) no way to figure out that it did that.
One approach taken by some multi-threaded applications (ECL comes to mind) is that the main thread is dedicated to handling asynchronous signals and work is done in other threads. In principle, it might be possible to do something similar in sage (probably with just 2 threads in total, normally). Then the signal handling thread can set up all kinds of flags that other threads can respond to whenever they are ready. This "cure" may be worse than the problem, though.
Replying to @nbruin:
One approach taken by some multi-threaded applications (ECL comes to mind) is that the main thread is dedicated to handling asynchronous signals and work is done in other threads.
The problem is not signal handling, the problem is that Python throws away exceptions.
Replying to @jdemeyer:
The problem is not signal handling, the problem is that Python throws away exceptions.
That's one way of looking at it, but it seems that the exceptions that are really problematic when they're thrown away are the ones stemming from asynchronous signals; at least that's the kind that triggers the reported behaviour in the ticket. It may be the case that splitting threads allows you to work around the behaviour in python without patching it.
Personally I think I can live with knowing that I shouldn't fully trust results from a sage session that has experienced an interruption. That would be my default assumption for computational software anyway. I'm not really advocating that we explore this option, but it seems a possibility.
Replying to @nbruin:
One approach taken by some multi-threaded applications (ECL comes to mind) is that the main thread is dedicated to handling asynchronous signals and work is done in other threads. In principle, it might be possible to do something similar in sage (probably with just 2 threads in total, normally). Then the signal handling thread can set up all kinds of flags that other threads can respond to whenever they are ready.
This is actually more or less how Python internally handles interrupts. It's not literally multi-threaded, but I don't think that this matters. When an interrupt occurs, it just sets a flag that the interpreter checks at suitable times.
So two possible fixes that I see (both involve patching Python):
Python should only check for signals when it can actually handle them.
Python should have a mechanism to deal with unraisable exceptions: say, a callback method __unraisable__
on the exception object. That way, we can re-enable the interrupt flag when a KeyboardInterrupt
exception is ignored.
I think that 2. can realistically be implemented, but I don't feel like fighting with Python upstream to make them accept that change (they are extremely conservative and it's hard to push any non-trivial changes).
I think there is a general logic error with AlarmInterrupt in that it can be raised in a destructor, where Python will then ignore it. This causes doctest timeout like:
Not sure what the right solution is, though. Ideally, the signal would be delivered as soon as the dtor is completed.
CC: @jdemeyer
Component: c_lib
Issue created by migration from https://trac.sagemath.org/ticket/24217