Skip to content

Recent SIGINT change breaks ipython / cysignals -- affects sagemath #1576

@tornaria

Description

@tornaria

Starting with 3.0.25 (i.e. after #1538) hitting control-C is not working properly in sagemath.

Background: sagemath uses cysignals so that signals can be handled when running extension code; cysignals installs a custom signal handler to catch signals while running extension code. When a signal is received, it unwinds and raises a python exception. This is used extensively in sagemath.

The issue is not tied with sagemath and can be easily reproduced from ipython as follows:

  • Create an extension module with a function that loops forever using cysignals to trap signals.
  • Load the module and run the function from ipython
  • Hit control-C: works with prompt_toolkit-3.0.24, doesn't work with prompt_toolkit-3.0.25

EXAMPLE

  1. Create a file forever.pyx:
from cysignals.signals cimport sig_on, sig_off

def run():
    sig_on()
    while True:
        pass
    sig_off()
  1. Compile this module with
$ cythonize -a -i forever.pyx
Compiling /tmp/forever.pyx because it changed.
[...]

After this you'll have an extension module, in my system the file is named forever.cpython-310-x86_64-linux-gnu.so.

  1. Run ipython with prompt_toolkit-3.0.24:
$ ipython
Python 3.10.2 (main, Jan 15 2022, 03:11:32) [GCC 10.2.1 20201203]
Type 'copyright', 'credits' or 'license' for more information
IPython 8.0.1 -- An enhanced Interactive Python. Type '?' for help.

In [1]: import forever

In [2]: forever.run()
^C---------------------------------------------------------------------------
KeyboardInterrupt                         Traceback (most recent call last)
Input In [2], in <module>
----> 1 forever.run()

File /tmp/forever.pyx:4, in forever.run()
      2 
      3 def run():
----> 4     sig_on()
      5     while True:
      6         pass

KeyboardInterrupt: 

In [3]: 
  1. Run ipython with prompt_toolkit-3.0.25:
$ ipython
Python 3.10.2 (main, Jan 15 2022, 03:11:32) [GCC 10.2.1 20201203]
Type 'copyright', 'credits' or 'license' for more information
IPython 8.0.1 -- An enhanced Interactive Python. Type '?' for help.

In [1]: import forever

In [2]: forever.run()
^C^C^C^C^C^C^C^C^C^C^C^C
  1. Sending a SIGINT from another process also doesn't work.
$ kill -INT 14853
[nothing happens]
  1. Sending a different signal works:
$ kill -ALRM 14853
[this happens in ipython]
---------------------------------------------------------------------------
AlarmInterrupt                            Traceback (most recent call last)
    [... skipping hidden 1 frame]

Input In [2], in <module>
----> 1 forever.run()

File /opt/sage/sage-git/develop/t/forever.pyx:4, in forever.run()
      3 def run():
----> 4     sig_on()
      5     while True:

AlarmInterrupt: 

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions