Skip to content

Commit 5e9a759

Browse files
author
Anselm Kruis
committed
Stackless issue python#80: fix an assertion failure during shutdown
This commit adds a test case to trigger an assertion failure during shutdown and fixes the bug. The assertion was added by my first attempt to fix issue python#60. Thanks to Masamitsu Murase for reporting the bug and for providing the fix. (grafted from 655f2a2292a237636849b4a82fb0a2dde1ee9847 and 109d5d067b14)
1 parent 1388cbe commit 5e9a759

File tree

3 files changed

+36
-2
lines changed

3 files changed

+36
-2
lines changed

Stackless/changelog.txt

+5
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,11 @@ What's New in Stackless 3.X.X?
1010

1111
*Release date: 20XX-XX-XX*
1212

13+
- https://bitbucket.org/stackless-dev/stackless/issue/80
14+
Fix an assertion failure during shutdown. The assertion was added by
15+
the first attempt to fix issue #60. Thanks to Masamitsu Murase
16+
for reporting the bug and for providing the fix.
17+
1318
- https://bitbucket.org/stackless-dev/stackless/issue/79
1419
Add __all__ to module stackless. Add entries to the module's __dict__
1520
for the computed properties (i.e. current, main, ...). This helps IDEs

Stackless/core/stacklesseval.c

+7-2
Original file line numberDiff line numberDiff line change
@@ -92,11 +92,16 @@ slp_cstack_new(PyCStackObject **cst, intptr_t *stackref, PyTaskletObject *task)
9292
intptr_t *stackbase;
9393
ptrdiff_t size;
9494

95+
ts = NULL;
9596
if (task && task->cstate) {
97+
/* usually a tasklet with a cstate has a valid
98+
tstate, but during shutdown (function slp_kill_tasks_with_stacks)
99+
the tstate may be NULL. The exact conditions are complicated. */
96100
ts = task->cstate->tstate;
97-
assert(ts);
98-
} else
101+
}
102+
if (ts == NULL) {
99103
ts = PyThreadState_GET();
104+
}
100105

101106
stackbase = ts->st.cstack_base;
102107
size = stackbase - stackref;

Stackless/unittests/test_defects.py

+24
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import sys
55
import types
66

7+
from stackless import _test_nostacklesscall as apply
78
from support import StacklessTestCase, captured_stderr
89

910

@@ -231,6 +232,29 @@ def func(current):
231232

232233
self.assertIsInstance(f_locals, dict)
233234

235+
236+
class TestShutdown(StacklessTestCase):
237+
def test_cstack_new(self):
238+
# test for issue #80 https://bitbucket.org/stackless-dev/stackless/issues/80/
239+
import subprocess
240+
rc = subprocess.call([sys.executable, "-S", "-E", "-c", """if 1:
241+
import stackless, sys
242+
from stackless import _test_nostacklesscall as apply
243+
244+
def func():
245+
global channel
246+
assert stackless.current.nesting_level == 0
247+
assert apply(lambda : stackless.current.nesting_level) == 1, "apply does not recurse"
248+
apply(channel.receive) # crash at nesting level 1
249+
250+
channel = stackless.channel()
251+
task = stackless.tasklet().bind(func, ()) # simplest tasklet
252+
task.run()
253+
sys.exit(42)
254+
"""])
255+
self.assertEqual(rc, 42)
256+
257+
234258
if __name__ == '__main__':
235259
import sys
236260
if not sys.argv[1:]:

0 commit comments

Comments
 (0)