Skip to content

Commit ee97ab4

Browse files
committed
Show a proper warning for leaks on PARI stack
1 parent 43d4865 commit ee97ab4

File tree

2 files changed

+25
-5
lines changed

2 files changed

+25
-5
lines changed

cypari2/pari_instance.pyx

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,18 @@ non-default argument following a default argument) works:
242242
Reset default precision for the following tests:
243243
244244
>>> pari.set_real_precision_bits(53)
245+
246+
Test that interrupts work properly:
247+
248+
>>> pari.allocatemem(8000000, 2**29)
249+
PARI stack size set to 8000000 bytes, maximum size set to ...
250+
>>> from cysignals.alarm import alarm, AlarmInterrupt
251+
>>> for i in range(1, 11):
252+
... try:
253+
... alarm(i/11.0)
254+
... pari.binomial(2**100, 2**22)
255+
... except AlarmInterrupt:
256+
... pass
245257
"""
246258

247259
#*****************************************************************************

cypari2/stack.pyx

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ from .paridecl cimport (avma, pari_mainstack, gnil, gcopy,
2727
is_universal_constant, is_on_stack,
2828
isclone, gclone, gclone_refc)
2929

30+
from warnings import warn
31+
3032

3133
cdef extern from *:
3234
int sig_on_count "cysigs.sig_on_count"
@@ -50,9 +52,13 @@ cdef void remove_from_pari_stack(Gen self):
5052
print(f"Expected: {<object>stackbottom}")
5153
print(f"Actual: {self}")
5254
if self.sp() != avma:
53-
print("ERROR: inconsistent avma when removing Gen from PARI stack")
54-
print(f"Expected: 0x{self.sp():x}")
55-
print(f"Actual: 0x{avma:x}")
55+
if avma > self.sp():
56+
print("ERROR: inconsistent avma when removing Gen from PARI stack")
57+
print(f"Expected: 0x{self.sp():x}")
58+
print(f"Actual: 0x{avma:x}")
59+
else:
60+
warn(f"cypari2 leaked {self.sp() - avma} bytes on the PARI stack",
61+
RuntimeWarning, stacklevel=2)
5662
stackbottom = n = self.next
5763
self.next = NULL
5864
reset_avma()
@@ -73,8 +79,10 @@ cdef inline Gen Gen_stack_new(GEN x):
7379
z.next = stackbottom
7480
stackbottom = <PyObject*>z
7581
if z.next is not <PyObject*>top_of_stack:
76-
if z.sp() > (<Gen>z.next).sp():
77-
raise SystemError("objects on PARI stack in invalid order")
82+
s0 = z.sp()
83+
s1 = (<Gen>z.next).sp()
84+
if s0 > s1:
85+
raise SystemError(f"objects on PARI stack in invalid order (first: 0x{s0:x}; next: 0x{s1:x})")
7886
return z
7987

8088

0 commit comments

Comments
 (0)