Skip to content

Reentrancy issue in sig_occurred() #221

@tornaria

Description

@tornaria

This is related but different from #215.

Reported sagemath/sage#38749 (comment) for a particular random seed, and after #216 it is permanent (see #181 (comment)).

Here's a log with sagemath 10.5 / python 3.13:

sage -t --long --warn-long 30.0 --random-seed=308265638168472780954235246279840024638 /usr/lib/python3.13/site-packages/sage/rings/integer.pyx
**********************************************************************
File "/usr/lib/python3.13/site-packages/sage/rings/integer.pyx", line 3074, in sage.rings.integer.Integer.divisors
Failed example:
    for i in range(20):           # long time                             # needs sage.libs.pari
        try:
            alarm(RDF.random_element(1e-3, 0.5))
            _ = n.divisors()
            cancel_alarm()  # we never get here
        except AlarmInterrupt:
            pass
Expected nothing
Got:
    Traceback (most recent call last):
      File "<frozen importlib._bootstrap>", line 653, in has_location
      File "signals.pyx", line 355, in cysignals.signals.python_check_interrupt
    cysignals.signals.AlarmInterrupt
    Exception ignored in: 'cysignals.signals.verify_exc_value'
    Traceback (most recent call last):
      File "<frozen importlib._bootstrap>", line 653, in has_location
      File "signals.pyx", line 355, in cysignals.signals.python_check_interrupt
    cysignals.signals.AlarmInterrupt: 
    Traceback (most recent call last):
      File "<frozen importlib._bootstrap>", line 653, in has_location
      File "signals.pyx", line 355, in cysignals.signals.python_check_interrupt
    cysignals.signals.AlarmInterrupt
    Exception ignored in: 'cysignals.signals.verify_exc_value'
    Traceback (most recent call last):
      File "<frozen importlib._bootstrap>", line 653, in has_location
      File "signals.pyx", line 355, in cysignals.signals.python_check_interrupt
    cysignals.signals.AlarmInterrupt: 
    Traceback (most recent call last):
      File "<frozen importlib._bootstrap>", line 653, in has_location
      File "signals.pyx", line 355, in cysignals.signals.python_check_interrupt
    cysignals.signals.AlarmInterrupt
    Exception ignored in: 'cysignals.signals.verify_exc_value'
    Traceback (most recent call last):
      File "<frozen importlib._bootstrap>", line 653, in has_location
      File "signals.pyx", line 355, in cysignals.signals.python_check_interrupt
    cysignals.signals.AlarmInterrupt: 
    Traceback (most recent call last):
      File "<frozen importlib._bootstrap>", line 653, in has_location
      File "signals.pyx", line 355, in cysignals.signals.python_check_interrupt
    cysignals.signals.AlarmInterrupt
    Exception ignored in: 'cysignals.signals.verify_exc_value'
    Traceback (most recent call last):
      File "<frozen importlib._bootstrap>", line 653, in has_location
      File "signals.pyx", line 355, in cysignals.signals.python_check_interrupt
    cysignals.signals.AlarmInterrupt: 
    Traceback (most recent call last):
      File "<frozen importlib._bootstrap>", line 653, in has_location
      File "signals.pyx", line 355, in cysignals.signals.python_check_interrupt
    cysignals.signals.AlarmInterrupt
    Exception ignored in: 'cysignals.signals.verify_exc_value'
    Traceback (most recent call last):
      File "<frozen importlib._bootstrap>", line 653, in has_location
      File "signals.pyx", line 355, in cysignals.signals.python_check_interrupt
    cysignals.signals.AlarmInterrupt: 
    Traceback (most recent call last):
      File "<frozen importlib._bootstrap>", line 653, in has_location
      File "signals.pyx", line 355, in cysignals.signals.python_check_interrupt
    cysignals.signals.AlarmInterrupt
    Exception ignored in: 'cysignals.signals.verify_exc_value'
    Traceback (most recent call last):
      File "<frozen importlib._bootstrap>", line 653, in has_location
      File "signals.pyx", line 355, in cysignals.signals.python_check_interrupt
    cysignals.signals.AlarmInterrupt: 
    Traceback (most recent call last):
      File "<frozen importlib._bootstrap>", line 653, in has_location
      File "signals.pyx", line 355, in cysignals.signals.python_check_interrupt
    cysignals.signals.AlarmInterrupt
    Exception ignored in: 'cysignals.signals.verify_exc_value'
    Traceback (most recent call last):
      File "<frozen importlib._bootstrap>", line 653, in has_location
      File "signals.pyx", line 355, in cysignals.signals.python_check_interrupt
    cysignals.signals.AlarmInterrupt: 
    Traceback (most recent call last):
      File "<frozen importlib._bootstrap>", line 653, in has_location
      File "signals.pyx", line 355, in cysignals.signals.python_check_interrupt
    cysignals.signals.AlarmInterrupt
    Exception ignored in: 'cysignals.signals.verify_exc_value'
    Traceback (most recent call last):
      File "<frozen importlib._bootstrap>", line 653, in has_location
      File "signals.pyx", line 355, in cysignals.signals.python_check_interrupt
    cysignals.signals.AlarmInterrupt: 
**********************************************************************

A minimal way to reproduce it with this file:

from math import prod
from sage.arith.misc import primes_first_n
from cysignals.alarm import alarm, AlarmInterrupt
from cysignals.tests import print_sig_occurred
from resource import getrusage, RUSAGE_SELF

def cputime():
    return sum(getrusage(RUSAGE_SELF)[:2])

n = prod(primes_first_n(25))

try:
    alarm(0.2)
    print(f"{cputime():5.2f}s first run")
    _ = n.divisors()
except AlarmInterrupt:
    print(f"{cputime():5.2f}s first alarm triggered")

try:
    alarm(0.04)
    print(f"{cputime():5.2f}s second run")
    _ = n.divisors()
except AlarmInterrupt:
    print(f"{cputime():5.2f}s second alarm triggered")

print(f"{cputime():5.2f}s done")

run from python as

$ python bug-sig_occurred.py 
 0.26s first run
 0.76s first alarm triggered
 0.76s second run
Traceback (most recent call last):
  File "<frozen importlib._bootstrap>", line 653, in has_location
  File "signals.pyx", line 355, in cysignals.signals.python_check_interrupt
cysignals.signals.AlarmInterrupt
Exception ignored in: 'cysignals.signals.verify_exc_value'
Traceback (most recent call last):
  File "<frozen importlib._bootstrap>", line 653, in has_location
  File "signals.pyx", line 355, in cysignals.signals.python_check_interrupt
cysignals.signals.AlarmInterrupt: 
 4.16s done

Note that the second alarm escapes; it is (printed and) ignored in verify_exc_value(), but the computation keeps going until the end.

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