Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

implement switching using the Stackman submodule #230

Merged
merged 25 commits into from
Jul 16, 2021

Conversation

kristjanvalur
Copy link
Collaborator

The Stackman project (http://github.com/kristjanvalur/stackman) aims to provide simple
stack switching code for modern platforms. The aim is to have application-agnostic code that
performs the basic functionality of saving machine registers and switching stack pointer, leaving the custom code of saving/restoring stack and choosing stack pointer to a user callback.

The resulting switching code is very succinct and easy to verfy.

This pull requests adds Stackman based switching for the supported platforms, which is GCC on
intel (x86 and x86_64) and ARM 32 hard float and aarch64.

@akruis
Copy link

akruis commented Jan 7, 2020

Cool, I'll have a look at it within the next few days.

@kristjanvalur
Copy link
Collaborator Author

kristjanvalur commented Jan 10, 2020 via email

Copy link

@akruis akruis left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi Kristján,

the url in .gitmodules points to your private repository and uses ssh. Please change it to a https URL of a official stackman repository.

Regards
Anselm

@akruis
Copy link

akruis commented Jan 12, 2020

How is stackman related to your previous work in issue #10 and https://bitbucket.org/stackless-dev/tealet/src/default/ ?

Additionally there's still a bug somewhere: I compliled the code with
./configure --prefix=/tmp/slp38 --with-pydebug CC=clang CPP='clang -E' and
make clean; make; make teststackless and got a segfault in

test_raise_exception_H (test_miscell.TestSwitchTrap) ... Fatal Python error: Segmentation fault

Current thread 0x00007f85db4ac140 (most recent call first):
File "/home/anselm/src/slp_ws/stackless38/Lib/unittest/case.py", line 178 in handle
File "/home/anselm/src/slp_ws/stackless38/Lib/unittest/case.py", line 743 in assertRaises
File "/home/anselm/src/slp_ws/stackless38/Stackless/unittests/test_miscell.py", line 436 in foo
Segmentation fault (core dumped)

(gdb) bt
#0  raise (sig=11) at ../sysdeps/unix/sysv/linux/raise.c:50
#1  0x0000000000714d37 in faulthandler_fatal_error (signum=11) at ./Modules/faulthandler.c:359
#2  <signal handler called>
#3  0x00000000005cbcff in slp_schedule_task_prepared (ts=0x1eebc70, result=0x7ffc29e44498, prev=0x7ffc29e44050, next=0x7f85daea0058, 
    stackless=0, did_switch=0x7ffc29e443e0) at Stackless/module/scheduling.c:1192
#4  0x00000000005c94db in slp_schedule_task (result=0x7ffc29e44498, prev=0x7f85d9ed37d8, next=0x7f85daea0058, stackless=0, 
    did_switch=0x7ffc29e443e0) at Stackless/module/scheduling.c:1018
#5  0x00000000007ac4ed in generic_channel_block (ts=0x1eebc70, result=0x7ffc29e44498, self=0x7f85d9cd7d78, dir=-1, stackless=0)
    at Stackless/module/channelobject.c:585
#6  0x00000000007ab875 in generic_channel_action (self=0x7f85d9cd7d78, arg=None, dir=-1, stackless=0)
    at Stackless/module/channelobject.c:473
#7  0x00000000007aa9e6 in impl_channel_receive (self=0x7f85d9cd7d78) at Stackless/module/channelobject.c:787
#8  0x00000000007ace75 in channel_receive (self=<_stackless.channel at remote 0x7f85d9cd7d78>) at Stackless/module/channelobject.c:814
#9  0x0000000000447bb3 in _PyMethodDef_RawFastCallDict (method=0x8d5f90 <channel_methods+96>, 
    self=<_stackless.channel at remote 0x7f85d9cd7d78>, args=0x7f85db009080, nargs=0, kwargs={}) at Objects/call.c:596
#10 0x00000000004457bd in _PyCFunction_FastCallDict (func=<built-in method receive of _stackless.channel object at remote 0x7f85d9cd7d78>, 
    args=0x7f85db009080, nargs=0, kwargs={}) at Objects/call.c:709
#11 0x0000000000446f4f in PyCFunction_Call (func=<built-in method receive of _stackless.channel object at remote 0x7f85d9cd7d78>, args=(), 
    kwargs={}) at Objects/call.c:965
#12 0x00000000005b9cb0 in do_call_core (func=<built-in method receive of _stackless.channel object at remote 0x7f85d9cd7d78>, callargs=(), 
    kwdict={}) at Python/ceval.c:5296
#13 0x00000000005b1e17 in slp_eval_frame_value (
    f=Frame 0x21bdde8, for file /home/anselm/src/slp_ws/stackless38/Lib/unittest/case.py, line 178, in handle (self=<_AssertRaisesContext(test_case=<TestSwitchTrap(_StacklessTestCase__enable_softswitch=False, _testMethodName='test_raise_exception_H', _outcome=<_Outcome(expecting_failure=False, result=<TextTestResult(failfast=False, failures=[], errors=[], testsRun=272, skipped=[(<TestBind(_StacklessTestCase__enable_softswitch=False, _testMethodName='test_rebind_main_H', _outcome=None, _testMethodDoc=None, _cleanups=[(<method at remote 0x7f85d9f098a8>, (), {})], _subtest=None, _type_equality_funcs={<type at remote 0x86a590>: 'assertDictEqual', <type at remote 0x8685a0>: 'assertListEqual', <type at remote 0x870e30>: 'assertTupleEqual', <type at remote 0x86f6c0>: 'assertSetEqual', <type at remote 0x86fb90>: 'assertSetEqual', <type at remote 0x874ae0>: 'assertMultiLineEqual'}, _StacklessTestCase__setup_called=False, _StacklessTestCase__uncollectable_tasklets=[], _StacklessTestCase__initial_cstack_serial=18, _StacklessT...(truncated), throwflag=0, retval=None) at Python/ceval.c:3468
#14 0x00000000005baaf1 in PyEval_EvalFrameEx_slp (
    f=Frame 0x21bdde8, for file /home/anselm/src/slp_ws/stackless38/Lib/unittest/case.py, line 178, in handle (self=<_AssertRaisesContext(test_case=<TestSwitchTrap(_StacklessTestCase__enable_softswitch=False, _testMethodName='test_raise_exception_H', _outcome=<_Outcome(expecting_failure=False, result=<TextTestResult(failfast=False, failures=[], errors=[], testsRun=272, skipped=[(<TestBind(_StacklessTestCase__enable_softswitch=False, _testMethodName='test_rebind_main_H', _outcome=None, _testMethodDoc=None, _cleanups=[(<method at remote 0x7f85d9f098a8>, (), {})], _subtest=None, _type_equality_funcs={<type at remote 0x86a590>: 'assertDictEqual', <type at remote 0x8685a0>: 'assertListEqual', <type at remote 0x870e30>: 'assertTupleEqual', <type at remote 0x86f6c0>: 'assertSetEqual', <type at remote 0x86fb90>: 'assertSetEqual', <type at remote 0x874ae0>: 'assertMultiLineEqual'}, _StacklessTestCase__setup_called=False, _StacklessTestCase__uncollectable_tasklets=[], _StacklessTestCase__initial_cstack_serial=18, _StacklessT...(truncated), throwflag=0, retval=None) at Python/ceval.c:4118
#15 0x00000000005c3361 in slp_frame_dispatch (
    f=Frame 0x21bdde8, for file /home/anselm/src/slp_ws/stackless38/Lib/unittest/case.py, line 178, in handle (self=<_AssertRaisesContext(test_case=<TestSwitchTrap(_StacklessTestCase__enable_softswitch=False, _testMethodName='test_raise_exception_H', _outcome=<_Outcome(expecting_failure=False, result=<TextTestResult(failfast=False, failures=[], errors=[], testsRun=272, skipped=[(<TestBind(_StacklessTestCase__enable_softswitch=False, _testMethodName='test_rebind_main_H', _outcome=None, _testMethodDoc=None, _cleanups=[(<method at remote 0x7f85d9f098a8>, (), {})], _subtest=None, _type_equality_funcs={<type at remote 0x86a590>: 'assertDictEqual', <type at remote 0x8685a0>: 'assertListEqual', <type at remote 0x870e30>: 'assertTupleEqual', <type at remote 0x86f6c0>: 'assertSetEqual', <type at remote 0x86fb90>: 'assertSetEqual', <type at remote 0x874ae0>: 'assertMultiLineEqual'}, _StacklessTestCase__setup_called=False, _StacklessTestCase__uncollectable_tasklets=[], _StacklessTest--Type <RET> for more, q to quit, c to continue without paging--
Case__initial_cstack_serial=18, _StacklessT...(truncated), 
    stopframe=Frame 0x215c1a8, for file /home/anselm/src/slp_ws/stackless38/Lib/unittest/case.py, line 743, in assertRaises (self=<TestSwitchTrap(_StacklessTestCase__enable_softswitch=False, _testMethodName='test_raise_exception_H', _outcome=<_Outcome(expecting_failure=False, result=<TextTestResult(failfast=False, failures=[], errors=[], testsRun=272, skipped=[(<TestBind(_StacklessTestCase__enable_softswitch=False, _testMethodName='test_rebind_main_H', _outcome=None, _testMethodDoc=None, _cleanups=[(<method at remote 0x7f85d9f098a8>, (), {})], _subtest=None, _type_equality_funcs={<type at remote 0x86a590>: 'assertDictEqual', <type at remote 0x8685a0>: 'assertListEqual', <type at remote 0x870e30>: 'assertTupleEqual', <type at remote 0x86f6c0>: 'assertSetEqual', <type at remote 0x86fb90>: 'assertSetEqual', <type at remote 0x874ae0>: 'assertMultiLineEqual'}, _StacklessTestCase__setup_called=False, _StacklessTestCase__uncollectable_tasklets=[], _StacklessTestCase__initial_cstack_serial=18, _StacklessTestCase__preexisting_threa...(truncated), exc=0, retval=None) at Stackless/core/stacklesseval.c:1044
#16 0x000000000044753f in function_code_fastcall (co=0x7f85dace9a00, args=0x215c378, nargs=4, 
    globals={'__name__': 'unittest.case', '__doc__': 'Test case implementation', '__package__': 'unittest', '__loader__': <SourceFileLoader(name='unittest.case', path='/home/anselm/src/slp_ws/stackless38/Lib/unittest/case.py') at remote 0x7f85dacd69b0>, '__spec__': <ModuleSpec(name='unittest.case', loader=<...>, origin='/home/anselm/src/slp_ws/stackless38/Lib/unittest/case.py', loader_state=None, submodule_search_locations=None, _set_fileattr=True, _cached='/home/anselm/src/slp_ws/stackless38/Lib/unittest/__pycache__/case.cpython-37.pyc', _initializing=False) at remote 0x7f85dacd6608>, '__file__': '/home/anselm/src/slp_ws/stackless38/Lib/unittest/case.py', '__cached__': '/home/anselm/src/slp_ws/stackless38/Lib/unittest/__pycache__/case.cpython-37.pyc', '__builtins__': {'__name__': 'builtins', '__doc__': "Built-in functions, exceptions, and other objects.\n\nNoteworthy: None is the `nil' object; Ellipsis represents `...' in slices.", '__package__': '', '__loader__': <type at remote 0x1f001a8>, '__spec__': <ModuleSpec(name...(truncated)) at Objects/call.c:370
#17 0x000000000044637e in _PyFunction_FastCallKeywords (func=<function at remote 0x7f85dabfae00>, stack=0x215c358, nargs=4, kwnames=0x0)
    at Objects/call.c:512
#18 0x00000000005b9829 in call_function (pp_stack=0x7ffc29e47358, oparg=4, kwnames=0x0) at Python/ceval.c:5269
#19 0x00000000005afd28 in slp_eval_frame_value (
    f=Frame 0x215c1a8, for file /home/anselm/src/slp_ws/stackless38/Lib/unittest/case.py, line 743, in assertRaises (self=<TestSwitchTrap(_StacklessTestCase__enable_softswitch=False, _testMethodName='test_raise_exception_H', _outcome=<_Outcome(expecting_failure=False, result=<TextTestResult(failfast=False, failures=[], errors=[], testsRun=272, skipped=[(<TestBind(_StacklessTestCase__enable_softswitch=False, _testMethodName='test_rebind_main_H', _outcome=None, _testMethodDoc=None, _cleanups=[(<method at remote 0x7f85d9f098a8>, (), {})], _subtest=None, _type_equality_funcs={<type at remote 0x86a590>: 'assertDictEqual', <type at remote 0x8685a0>: 'assertListEqual', <type at remote 0x870e30>: 'assertTupleEqual', <type at remote 0x86f6c0>: 'assertSetEqual', <type at remote 0x86fb90>: 'assertSetEqual', <type at remote 0x874ae0>: 'assertMultiLineEqual'}, _StacklessTestCase__setup_called=False, _StacklessTestCase__uncollectable_tasklets=[], _StacklessTestCase__initial_cstack_serial=18, _StacklessTestCase__preexisting_threa...(truncated), throwflag=0, retval=None) at Python/ceval.c:3371
#20 0x00000000005baaf1 in PyEval_EvalFrameEx_slp (
    f=Frame 0x215c1a8, for file /home/anselm/src/slp_ws/stackless38/Lib/unittest/case.py, line 743, in assertRaises (self=<TestSwitchTrap(_StacklessTestCase__enable_softswitch=False, _testMethodName='test_raise_exception_H', _outcome=<_Outcome(expecting_failure=False, result=<TextTestResult(failfast=False, failures=[], errors=[], testsRun=272, skipped=[(<TestBind(_StacklessTestCase__enable_softswitch=False, _testMethodName='test_rebind_main_H', _outcome=None, _testMethodDoc=None, _cleanups=[(<method at remote 0x7f85d9f098a8>, (), {})], _subtest=None, _type_equality_funcs={<type at remote 0x86a590>: 'assertDictEqual', <type at remote 0x8685a0>: 'assertListEqual', <type at remote 0x870e30>: 'assertTupleEqual', <type at remote 0x86f6c0>: 'assertSetEqual', <type at remote 0x86fb90>: 'assertSetEqual', <type at remote 0x874ae0>: 'assertMultiLineEqual'}, _StacklessTestCase__setup_called=False, _StacklessTestCase__uncollectable_tasklets=[], _StacklessTestCase__initial_cstack_serial=18, _StacklessTestCase__preexisting_threa...(truncated), throwflag=0, retval=None) at Python/ceval.c:4118
#21 0x00000000005c3361 in slp_frame_dispatch (
    f=Frame 0x215c1a8, for file /home/anselm/src/slp_ws/stackless38/Lib/unittest/case.py, line 743, in assertRaises (self=<TestSwitchTrap(_StacklessTestCase__enable_softswitch=False, _testMethodName='test_raise_exception_H', _outcome=<_Outcome(expecting_failure=False, result=<TextTestResult(failfast=False, failures=[], errors=[], testsRun=272, skipped=[(<TestBind(_StacklessTestCase__enable_softswitch=False, _testMethodName='test_rebind_main_H', _outcome=None, _testMethodDoc=None, _cleanups=[(<method at remote 0x7f85d9f098a8>, (), {})], _subtest=None, _type_equality_funcs={<type at remote 0x86a590>: 'assertDictEqual', <type at remote 0x8685a0>: 'assertListEqual', <type at remote 0x870e30>: 'assertTupleEqual', <type at remote 0x86f6c0>: 'assertSetEqual', <type at remote 0x86fb90>: 'assertSetEqual', <type at remote 0x874ae0>: 'assertMultiLineEqual'}, _StacklessTestCase__setup_called=False, _StacklessTestCase__uncollectable_tasklets=[], _StacklessTestCase__initial_cstack_seria--Type <RET> for more, q to quit, c to continue without paging--
l=18, _StacklessTestCase__preexisting_threa...(truncated), 
    stopframe=Frame 0x7f85d9cbc818, for file /home/anselm/src/slp_ws/stackless38/Stackless/unittests/test_miscell.py, line 436, in foo (), 
    exc=0, retval=None) at Stackless/core/stacklesseval.c:1044
#22 0x00000000005bcff4 in _PyEval_EvalCodeWithName (_co=<code at remote 0x7f85dacf6f40>, 
    globals={'__name__': 'unittest.case', '__doc__': 'Test case implementation', '__package__': 'unittest', '__loader__': <SourceFileLoader(name='unittest.case', path='/home/anselm/src/slp_ws/stackless38/Lib/unittest/case.py') at remote 0x7f85dacd69b0>, '__spec__': <ModuleSpec(name='unittest.case', loader=<...>, origin='/home/anselm/src/slp_ws/stackless38/Lib/unittest/case.py', loader_state=None, submodule_search_locations=None, _set_fileattr=True, _cached='/home/anselm/src/slp_ws/stackless38/Lib/unittest/__pycache__/case.cpython-37.pyc', _initializing=False) at remote 0x7f85dacd6608>, '__file__': '/home/anselm/src/slp_ws/stackless38/Lib/unittest/case.py', '__cached__': '/home/anselm/src/slp_ws/stackless38/Lib/unittest/__pycache__/case.cpython-37.pyc', '__builtins__': {'__name__': 'builtins', '__doc__': "Built-in functions, exceptions, and other objects.\n\nNoteworthy: None is the `nil' object; Ellipsis represents `...' in slices.", '__package__': '', '__loader__': <type at remote 0x1f001a8>, '__spec__': <ModuleSpec(name...(truncated), locals=0x0, args=0x7f85d9cbc9b0, argcount=3, kwnames=0x0, 
    kwargs=0x7f85d9cbc9c8, kwcount=0, kwstep=1, defs=0x0, defcount=0, kwdefs=0x0, closure=0x0, name='assertRaises', 
    qualname='TestCase.assertRaises') at Python/ceval.c:4580
#23 0x00000000004466b9 in _PyFunction_FastCallKeywords (func=<function at remote 0x7f85dab89338>, stack=0x7f85d9cbc9b0, nargs=3, 
    kwnames=0x0) at Objects/call.c:537
#24 0x00000000005b9829 in call_function (pp_stack=0x7ffc29e49b08, oparg=3, kwnames=0x0) at Python/ceval.c:5269
#25 0x00000000005afd28 in slp_eval_frame_value (
    f=Frame 0x7f85d9cbc818, for file /home/anselm/src/slp_ws/stackless38/Stackless/unittests/test_miscell.py, line 436, in foo (), 
    throwflag=0, retval=None) at Python/ceval.c:3371
#26 0x00000000005baaf1 in PyEval_EvalFrameEx_slp (
    f=Frame 0x7f85d9cbc818, for file /home/anselm/src/slp_ws/stackless38/Stackless/unittests/test_miscell.py, line 436, in foo (), 
    throwflag=0, retval=None) at Python/ceval.c:4118
#27 0x00000000005c3361 in slp_frame_dispatch (
    f=Frame 0x7f85d9cbc818, for file /home/anselm/src/slp_ws/stackless38/Stackless/unittests/test_miscell.py, line 436, in foo (), 
    stopframe=<_stackless.cframe at remote 0x7f85d9c9a790>, exc=0, retval=None) at Stackless/core/stacklesseval.c:1044
#28 0x00000000005bcff4 in _PyEval_EvalCodeWithName (_co=<code at remote 0x7f85d9ec4c40>, 
    globals={'__name__': 'test_miscell', '__doc__': None, '__package__': '', '__loader__': <SourceFileLoader(name='test_miscell', path='/home/anselm/src/slp_ws/stackless38/Stackless/unittests/test_miscell.py') at remote 0x7f85d9f28c20>, '__spec__': <ModuleSpec(name='test_miscell', loader=<...>, origin='/home/anselm/src/slp_ws/stackless38/Stackless/unittests/test_miscell.py', loader_state=None, submodule_search_locations=None, _set_fileattr=True, _cached='/home/anselm/src/slp_ws/stackless38/Stackless/unittests/__pycache__/test_miscell.cpython-37.pyc', _initializing=False) at remote 0x7f85d9f28058>, '__file__': '/home/anselm/src/slp_ws/stackless38/Stackless/unittests/test_miscell.py', '__cached__': '/home/anselm/src/slp_ws/stackless38/Stackless/unittests/__pycache__/test_miscell.cpython-37.pyc', '__builtins__': {'__name__': 'builtins', '__doc__': "Built-in functions, exceptions, and other objects.\n\nNoteworthy: None is the `nil' object; Ellipsis represents `...' in slices.", '__package__': '', '__loader__': <type at remot...(truncated), locals=0x0, args=0x7f85db009080, argcount=0, kwnames=0x0, kwargs=0x0, 
    kwcount=0, kwstep=2, defs=0x0, defcount=0, kwdefs=0x0, closure=(<cell at remote 0x7f85d9ca73b8>, <cell at remote 0x7f85d9ca7478>), 
    name='foo', qualname='TestSwitchTrap.test_raise_exception.<locals>.foo') at Python/ceval.c:4580
#29 0x00000000004455ad in _PyFunction_FastCallDict (func=<function at remote 0x7f85d9cbb110>, args=0x7f85db009080, nargs=0, kwargs=0x0)
    at Objects/call.c:479
#30 0x0000000000446be2 in PyObject_Call (callable=<function at remote 0x7f85d9cbb110>, args=(), kwargs=0x0) at Objects/call.c:272
#31 0x00000000005bf492 in run_cframe (f=<_stackless.cframe at remote 0x7f85d9c9a790>, exc=0, retval=None)
    at Stackless/core/cframeobject.c:244
#32 0x00000000005c6858 in slp_frame_dispatch_top (retval=None) at Stackless/core/stacklesseval.c:1079
#33 0x00000000005c3179 in slp_run_tasklet () at Stackless/core/stacklesseval.c:304
#34 0x00000000005c287a in slp_eval_frame (f=Frame 0x1f3b6c8, for file Stackless/unittests/runAll.py, line 31, in <module> ())
    at Stackless/core/stacklesseval.c:392
#35 0x00000000005c2ad0 in climb_stack_and_eval_frame (f=Frame 0x1f3b6c8, for file Stackless/unittests/runAll.py, line 31, in <module> ())
--Type <RET> for more, q to quit, c to continue without paging--
    at Stackless/core/stacklesseval.c:269
#36 0x00000000005c231b in slp_eval_frame (f=Frame 0x1f3b6c8, for file Stackless/unittests/runAll.py, line 31, in <module> ())
    at Stackless/core/stacklesseval.c:352
#37 0x00000000005bd08e in _PyEval_EvalCodeWithName (_co=<code at remote 0x7f85daea7580>, 
    globals={'__name__': '__main__', '__doc__': '\nrunAll.py\n\nRuns all test-cases in files named test_*.py.\nShould be run in the folder Stackless/unittests.\n\nThis driver reuses the CPython test.regrtest driver and\nsupports its options.\n', '__package__': None, '__loader__': <SourceFileLoader(name='__main__', path='Stackless/unittests/runAll.py') at remote 0x7f85daf08400>, '__spec__': None, '__annotations__': {}, '__builtins__': <module at remote 0x7f85dafd6a58>, '__file__': '/home/anselm/src/slp_ws/stackless38/build/test_python_4581/Stackless/unittests/runAll.py', '__cached__': None, 'absolute_import': <_Feature(optional=(2, 5, 0, 'alpha', 1), mandatory=(3, 0, 0, 'alpha', 0), compiler_flag=16384) at remote 0x7f85dae255a0>, 'os': <module at remote 0x7f85dae8c658>, 'support': <module at remote 0x7f85dae1b358>, 'libregrtest': <module at remote 0x7f85dae34758>, 'test_path': ['/home/anselm/src/slp_ws/stackless38/Stackless/unittests', '/home/anselm/src/slp_ws/stackless38/Lib/test'], 'path': '/home/anselm/src/slp_ws/stack...(truncated), 
    locals={'__name__': '__main__', '__doc__': '\nrunAll.py\n\nRuns all test-cases in files named test_*.py.\nShould be run in the folder Stackless/unittests.\n\nThis driver reuses the CPython test.regrtest driver and\nsupports its options.\n', '__package__': None, '__loader__': <SourceFileLoader(name='__main__', path='Stackless/unittests/runAll.py') at remote 0x7f85daf08400>, '__spec__': None, '__annotations__': {}, '__builtins__': <module at remote 0x7f85dafd6a58>, '__file__': '/home/anselm/src/slp_ws/stackless38/build/test_python_4581/Stackless/unittests/runAll.py', '__cached__': None, 'absolute_import': <_Feature(optional=(2, 5, 0, 'alpha', 1), mandatory=(3, 0, 0, 'alpha', 0), compiler_flag=16384) at remote 0x7f85dae255a0>, 'os': <module at remote 0x7f85dae8c658>, 'support': <module at remote 0x7f85dae1b358>, 'libregrtest': <module at remote 0x7f85dae34758>, 'test_path': ['/home/anselm/src/slp_ws/stackless38/Stackless/unittests', '/home/anselm/src/slp_ws/stackless38/Lib/test'], 'path': '/home/anselm/src/slp_ws/stack...(truncated), args=0x0, argcount=0, kwnames=0x0, kwargs=0x0, kwcount=0, kwstep=2, 
    defs=0x0, defcount=0, kwdefs=0x0, closure=0x0, name=0x0, qualname=0x0) at Python/ceval.c:4584
#38 0x0000000000592f35 in PyEval_EvalCodeEx (_co=<code at remote 0x7f85daea7580>, 
    globals={'__name__': '__main__', '__doc__': '\nrunAll.py\n\nRuns all test-cases in files named test_*.py.\nShould be run in the folder Stackless/unittests.\n\nThis driver reuses the CPython test.regrtest driver and\nsupports its options.\n', '__package__': None, '__loader__': <SourceFileLoader(name='__main__', path='Stackless/unittests/runAll.py') at remote 0x7f85daf08400>, '__spec__': None, '__annotations__': {}, '__builtins__': <module at remote 0x7f85dafd6a58>, '__file__': '/home/anselm/src/slp_ws/stackless38/build/test_python_4581/Stackless/unittests/runAll.py', '__cached__': None, 'absolute_import': <_Feature(optional=(2, 5, 0, 'alpha', 1), mandatory=(3, 0, 0, 'alpha', 0), compiler_flag=16384) at remote 0x7f85dae255a0>, 'os': <module at remote 0x7f85dae8c658>, 'support': <module at remote 0x7f85dae1b358>, 'libregrtest': <module at remote 0x7f85dae34758>, 'test_path': ['/home/anselm/src/slp_ws/stackless38/Stackless/unittests', '/home/anselm/src/slp_ws/stackless38/Lib/test'], 'path': '/home/anselm/src/slp_ws/stack...(truncated), 
    locals={'__name__': '__main__', '__doc__': '\nrunAll.py\n\nRuns all test-cases in files named test_*.py.\nShould be run in the folder Stackless/unittests.\n\nThis driver reuses the CPython test.regrtest driver and\nsupports its options.\n', '__package__': None, '__loader__': <SourceFileLoader(name='__main__', path='Stackless/unittests/runAll.py') at remote 0x7f85daf08400>, '__spec__': None, '__annotations__': {}, '__builtins__': <module at remote 0x7f85dafd6a58>, '__file__': '/home/anselm/src/slp_ws/stackless38/build/test_python_4581/Stackless/unittests/runAll.py', '__cached__': None, 'absolute_import': <_Feature(optional=(2, 5, 0, 'alpha', 1), mandatory=(3, 0, 0, 'alpha', 0), compiler_flag=16384) at remote 0x7f85dae255a0>, 'os': <module at remote 0x7f85dae8c658>, 'support': <module at remote 0x7f85dae1b358>, 'libregrtest': <module at remote 0x7f85dae34758>, 'test_path': ['/home/anselm/src/slp_ws/stackless38/Stackless/unittests', '/home/anselm/src/slp_ws/stackless38/Lib/test'], 'path': '/home/anselm/src/slp_ws/stack...(truncated), args=0x0, argcount=0, kws=0x0, kwcount=0, defs=0x0, defcount=0, kwdefs=0x0, 
    closure=0x0) at Python/ceval.c:4618
#39 0x0000000000592d8e in PyEval_EvalCode (co=<code at remote 0x7f85daea7580>, 
    globals={'__name__': '__main__', '__doc__': '\nrunAll.py\n\nRuns all test-cases in files named test_*.py.\nShould be run in the folder Stackless/unittests.\n\nThis driver reuses the CPython test.regrtest driver and\nsupports its options.\n', '__package__': None, '__loader__': <SourceFileLoader(name='__main__', path='Stackless/unittests/runAll.py') at remote 0x7f85daf08400>, '__spec__': None, '__annotations__': {}, '__builtins__': <module at remote 0x7f85dafd6a58>, '__file__': '/home/anselm/src/slp_ws/stackless38/build/test_python_4581/Stackless/unittests/runAll.py', '__cached__': None, 'absolute_import': <_Feature(optional=(2, 5, 0, 'alpha', 1), mandatory=(3, 0, 0, 'alpha', 0), compiler_flag=16384) at remote 0x7f85dae255a0>, 'os': <module at remote 0x7f85dae8c658>, 'support': <module at remote 0x7f85dae1b358>, 'libregrtest': <module at remote 0x7f85dae34758>, 'test_path': ['/home/anselm/src/slp_ws/stackless38/Stackless/unittests', '/home/anselm/src/slp_ws/stackless38/L--Type <RET> for more, q to quit, c to continue without paging--
ib/test'], 'path': '/home/anselm/src/slp_ws/stack...(truncated), 
    locals={'__name__': '__main__', '__doc__': '\nrunAll.py\n\nRuns all test-cases in files named test_*.py.\nShould be run in the folder Stackless/unittests.\n\nThis driver reuses the CPython test.regrtest driver and\nsupports its options.\n', '__package__': None, '__loader__': <SourceFileLoader(name='__main__', path='Stackless/unittests/runAll.py') at remote 0x7f85daf08400>, '__spec__': None, '__annotations__': {}, '__builtins__': <module at remote 0x7f85dafd6a58>, '__file__': '/home/anselm/src/slp_ws/stackless38/build/test_python_4581/Stackless/unittests/runAll.py', '__cached__': None, 'absolute_import': <_Feature(optional=(2, 5, 0, 'alpha', 1), mandatory=(3, 0, 0, 'alpha', 0), compiler_flag=16384) at remote 0x7f85dae255a0>, 'os': <module at remote 0x7f85dae8c658>, 'support': <module at remote 0x7f85dae1b358>, 'libregrtest': <module at remote 0x7f85dae34758>, 'test_path': ['/home/anselm/src/slp_ws/stackless38/Stackless/unittests', '/home/anselm/src/slp_ws/stackless38/Lib/test'], 'path': '/home/anselm/src/slp_ws/stack...(truncated)) at Python/ceval.c:525
#40 0x00000000006491a4 in run_mod (mod=0x1f66078, filename='Stackless/unittests/runAll.py', 
    globals={'__name__': '__main__', '__doc__': '\nrunAll.py\n\nRuns all test-cases in files named test_*.py.\nShould be run in the folder Stackless/unittests.\n\nThis driver reuses the CPython test.regrtest driver and\nsupports its options.\n', '__package__': None, '__loader__': <SourceFileLoader(name='__main__', path='Stackless/unittests/runAll.py') at remote 0x7f85daf08400>, '__spec__': None, '__annotations__': {}, '__builtins__': <module at remote 0x7f85dafd6a58>, '__file__': '/home/anselm/src/slp_ws/stackless38/build/test_python_4581/Stackless/unittests/runAll.py', '__cached__': None, 'absolute_import': <_Feature(optional=(2, 5, 0, 'alpha', 1), mandatory=(3, 0, 0, 'alpha', 0), compiler_flag=16384) at remote 0x7f85dae255a0>, 'os': <module at remote 0x7f85dae8c658>, 'support': <module at remote 0x7f85dae1b358>, 'libregrtest': <module at remote 0x7f85dae34758>, 'test_path': ['/home/anselm/src/slp_ws/stackless38/Stackless/unittests', '/home/anselm/src/slp_ws/stackless38/Lib/test'], 'path': '/home/anselm/src/slp_ws/stack...(truncated), 
    locals={'__name__': '__main__', '__doc__': '\nrunAll.py\n\nRuns all test-cases in files named test_*.py.\nShould be run in the folder Stackless/unittests.\n\nThis driver reuses the CPython test.regrtest driver and\nsupports its options.\n', '__package__': None, '__loader__': <SourceFileLoader(name='__main__', path='Stackless/unittests/runAll.py') at remote 0x7f85daf08400>, '__spec__': None, '__annotations__': {}, '__builtins__': <module at remote 0x7f85dafd6a58>, '__file__': '/home/anselm/src/slp_ws/stackless38/build/test_python_4581/Stackless/unittests/runAll.py', '__cached__': None, 'absolute_import': <_Feature(optional=(2, 5, 0, 'alpha', 1), mandatory=(3, 0, 0, 'alpha', 0), compiler_flag=16384) at remote 0x7f85dae255a0>, 'os': <module at remote 0x7f85dae8c658>, 'support': <module at remote 0x7f85dae1b358>, 'libregrtest': <module at remote 0x7f85dae34758>, 'test_path': ['/home/anselm/src/slp_ws/stackless38/Stackless/unittests', '/home/anselm/src/slp_ws/stackless38/Lib/test'], 'path': '/home/anselm/src/slp_ws/stack...(truncated), flags=0x7ffc29e545b0, arena=0x7f85daea33a0) at Python/pythonrun.c:1058
#41 0x0000000000647c3e in PyRun_FileExFlags (fp=0x1ef1a60, filename_str=0x7f85daefebd0 "Stackless/unittests/runAll.py", start=257, 
    globals={'__name__': '__main__', '__doc__': '\nrunAll.py\n\nRuns all test-cases in files named test_*.py.\nShould be run in the folder Stackless/unittests.\n\nThis driver reuses the CPython test.regrtest driver and\nsupports its options.\n', '__package__': None, '__loader__': <SourceFileLoader(name='__main__', path='Stackless/unittests/runAll.py') at remote 0x7f85daf08400>, '__spec__': None, '__annotations__': {}, '__builtins__': <module at remote 0x7f85dafd6a58>, '__file__': '/home/anselm/src/slp_ws/stackless38/build/test_python_4581/Stackless/unittests/runAll.py', '__cached__': None, 'absolute_import': <_Feature(optional=(2, 5, 0, 'alpha', 1), mandatory=(3, 0, 0, 'alpha', 0), compiler_flag=16384) at remote 0x7f85dae255a0>, 'os': <module at remote 0x7f85dae8c658>, 'support': <module at remote 0x7f85dae1b358>, 'libregrtest': <module at remote 0x7f85dae34758>, 'test_path': ['/home/anselm/src/slp_ws/stackless38/Stackless/unittests', '/home/anselm/src/slp_ws/stackless38/Lib/test'], 'path': '/home/anselm/src/slp_ws/stack...(truncated), 
    locals={'__name__': '__main__', '__doc__': '\nrunAll.py\n\nRuns all test-cases in files named test_*.py.\nShould be run in the folder Stackless/unittests.\n\nThis driver reuses the CPython test.regrtest driver and\nsupports its options.\n', '__package__': None, '__loader__': <SourceFileLoader(name='__main__', path='Stackless/unittests/runAll.py') at remote 0x7f85daf08400>, '__spec__': None, '__annotations__': {}, '__builtins__': <module at remote 0x7f85dafd6a58>, '__file__': '/home/anselm/src/slp_ws/stackless38/build/test_python_4581/Stackless/unittests/runAll.py', '__cached__': None, 'absolute_import': <_Feature(optional=(2, 5, 0, 'alpha', 1), mandatory=(3, 0, 0, 'alpha', 0), compiler_flag=16384) at remote 0x7f85dae255a0>, 'os': <module at remote 0x7f85dae8c658>, 'support': <module at remote 0x7f85dae1b358>, 'libregrtest': <module at remote 0x7f85dae34758>, 'test_path': ['/home/anselm/src/slp_ws/stackless38/Stackless/unittests', '/home/anselm/src/slp_ws/stackless38/Lib/test'], 'path': '/home/anselm/src/slp_ws/stack...(truncated), closeit=1, flags=0x7ffc29e545b0) at Python/pythonrun.c:1009
#42 0x00000000006467e4 in PyRun_SimpleFileExFlags (fp=0x1ef1a60, filename=0x7f85daefebd0 "Stackless/unittests/runAll.py", closeit=1, 
    flags=0x7ffc29e545b0) at Python/pythonrun.c:431
#43 0x0000000000645fff in PyRun_AnyFileExFlags (fp=0x1ef1a60, filename=0x7f85daefebd0 "Stackless/unittests/runAll.py", closeit=1, 
    flags=0x7ffc29e545b0) at Python/pythonrun.c:85
--Type <RET> for more, q to quit, c to continue without paging--
#44 0x000000000042ec18 in pymain_run_file (fp=0x1ef1a60, filename=0x1ee9940 L"Stackless/unittests/runAll.py", p_cf=0x7ffc29e545b0)
    at Modules/main.c:423
#45 0x000000000042e38f in pymain_run_filename (pymain=0x7ffc29e54640, cf=0x7ffc29e545b0) at Modules/main.c:1518
#46 0x000000000042b605 in pymain_run_python (pymain=0x7ffc29e54640) at Modules/main.c:2518
#47 0x000000000042a39f in pymain_main (pymain=0x7ffc29e54640) at Modules/main.c:2660
#48 0x000000000042a477 in _Py_UnixMain (argc=6, argv=0x7ffc29e54898) at Modules/main.c:2695
#49 0x0000000000427712 in main (argc=6, argv=0x7ffc29e54898) at ./Programs/python.c:15

@kristjanvalur
Copy link
Collaborator Author

I've changed it to https, but the "stackman" project is currently owned by me. It is a public repository. We can discuss transfering it to the stackless project, if you like this approach. I think it would be a good idea in general to decouple the stack manipulation in the way that i'm doing.
There are other projects using this submodule, including "tealet" which is a separate stack slicing library.

@kristjanvalur
Copy link
Collaborator Author

Hi Anselm. For a bit of background:

  • I've recently started working again on the tealet project. It is now under github.com/kristjanvalur/libtealet.
  • I then realized that the pure stack switching code might be usable for other projects, without defining stack saving semantics and everything. So, I started Stackman as a library of pure stack switching implementation, for a client library to define the semantics. The Readme I think explains it a bit. https://github.com/kristjanvalur/stackman/blob/master/README.md
  • This pull request just pulls in new assembler code, while still using the same stack management code that stackless already uses. In contrast, my old PR that you mention replaced all of stackless stack managemen with different code from libtealet.
  • Similarly, libtealet will also use stackman, but using its own stack saving / restring calback.

So, it is interesting that we get a crash with clang. It is possible that the assembly code generator doesn't work with that, I didn't test it. There are unittests for stackman, but I don't have CI yet. I'll investigate, and set up a CI suite to test a set of platforms.
I did, however, test this PR using standard config settings on linux x86-64.

So, some things I need to fix, so please give me a few days to look into that.
Cheers!

@kristjanvalur
Copy link
Collaborator Author

Odd. I can repro this, It happens during hard switching for test_raise_exception. after TASKLET_CLAIMVAL() in line 1192 in scheduling.c, retval is NULL. It seems to be because the prev pointer is bogus. I'll look into this.

@kristjanvalur
Copy link
Collaborator Author

Ok, it turns out that clang doesn't respect the same attr((optimize)) that gcc does. In particular, I cannot tell it to skip frame pointers, or perform optimization.
This causes it to create code that refers to an invalid base pointer.

I can see if I can get clang to work correctly, at least on x64. It is unfortunate that I cannot mandate a certain optimization level for a function using attr. for example, with -O1, it will perform a tail call for the second call to the callback, something which I am unsure if is valid!

For now, I have to make extra checks for clang.

@akruis
Copy link

akruis commented Jan 18, 2020

Hi,

now the --pydebug tests pass, at least for x86_64 on my old computer at home. It was by pure chance, that I used clang for my very first test.

I appreciate your work very much. We should replace the old Stackless code by stackman once it is sufficiently mature.

A few comments about your patch

About optimisation and stack switching: the Stackless stack switching code relies on the respective ABI (application binary interface) specification in order to know register usage and stack layout. Unfortunately the ABI specification does not apply to inlined functions and every C compiler is free to inline a function except in one single case: if the compiler does not know the called function. Fortunately the C standard guarantees to read the value of a volatile variable from memory on each access. If you call a function using a volatile pointer, the compiler must not infer the called function from the initialisation of the pointer and therefore the compiler can't inline the function. See #183 for an example. This consideration might apply to stackman too.

The Python Contributor Licensing Agreement requires, that the initial licence of a patch is on of Academic Free License v. 2.1 or Apache License, Version 2.0. Your stackman code uses the MIT licence. I wonder, if this could cause problems?

Starting with commit f653fd4 (bpo-35296) make install installs the internal API, that's Include/internal/*.h. You probably want to rearrange the stackman headers to live directly in Include/internal. Otherwise you need to patch "make install", the Windows installer and the Anaconda build scripts to copy Include/internal/stackman/**/*

Makefile.pre.in contains a list of all header files. You should add stackman headers to this list.

And we need to make sure, that the official source archive of Stackless contains a copy of the required stackman files. I use the script Stackless/Tools/create_source_archive.sh to create the archive. Probably it needs a patch.

About the stackman repository: once stackman is stable we could include a copy of the files in the stackless repository. Otherwise I would prefer a clone under https://github.com/stackless-dev/stackman. There is always a risk, that a private github repository disappears.

Finally the change needs to be documented in Stackless/changelog.txt. Eventually the section "Building Stackless" in Stackless/readme.txt needs an update too (regarding the git submodule usage).

@kristjanvalur
Copy link
Collaborator Author

Hi Anselm, thanks for your comments.

Regarding ABI, I have been careful to use the documented platform ABI whenever possible. I have changed the x86-64 on unix to save the floating point status variables as already done in the stackless code.

The main change stackman does is that the platform function is essentially fixed, and the implementation is from the callback. If I understand you correctly, you are concerned that a compiler, using whole program optimization, might bypass the function call-by-pointer and instead inline the function in the stackman_switch() function.
You are right that the inline assembly is fragile and subject to the compilers whims. Although I actually fail to see that inlining the function might be problematic, a compiler still may turn out to do weird stuff with the base pointer, etc, as it does for example on 32bit ARM (where it restores the stack pointer using it, if not instructed otherwise). The GNU compiler does seem to obey the attr(optimize), and correctly applies the requested level of optimization, uses a frame pointer (or not),etc. But other compilers are more fickle, such as clang. Also, the behaviour or GCC might change in the future.

But having a callback also adds a different facility: The stackman_switch() function is fixed, regardless of the application. This allows us to alternatively implement it using pure assembly. And in fact, this is how I have solved the clang problem for stackless. We can use gcc to generate the assembly code (using gcc -S), verify that it correct, and then use this assembler in applications that are created by unix-like toolchains. I will add a macro to stackman to prefer assembly implementation over inline assembly, if both are available. I will also generate the correct .S files for the supplied platforms.

Windows is, of course, different, since the .sln files need to be changed. Also, windows assembler doesn't do C Preprocessing (as cc does with .S files)

I'll see about making the callback pointer volatile. I'll look at your other suggestsins too (its been quite long since I worked on Stackless, my mind gets rusty). I'll also be happy to transfer ownership of this to the Stackless team, or we can clone it into there, whatever. As for the license, it was my understanding that the MIT was the most permissive license there is. I can check if adding MIT licensed code into python/stackless is problematic. Otherwise, I'm fine with changing the license.

@kristjanvalur
Copy link
Collaborator Author

I read up on #183 and under stand your concern. I.e. if the entire function is inlined then the generated inline assembly code no longer works.
As I explained, gcc seems to be safe from this (unless you have a counterexample) but the most robust way, and stable, is IMHO to simply use (non-inline) assembly which will force a function call as well. But, I can also add a shim layer to do a single call indirection using a volatile pointer, which should also force a proper function call.

@alanjds
Copy link

alanjds commented Jun 16, 2020

As for the license, it was my understanding that the MIT was the most permissive license there is. I can check if adding MIT licensed code into python/stackless is problematic. Otherwise, I'm fine with changing the license.

Not a lawyer here, but my understanding of Apache main difference is the implied protection from of possible patents others may have on the contributed code. This means that, even the code being opensource, MIT license could allow someone to patent software and sue users.

See: https://snyk.io/blog/mit-apache-bsd-fairest-of-them-all/

In addition, this latest version has two patent clauses. The first states the software can be used regardless of software patents which are in effect, without any further obligations. The second states that software users can’t initiate litigation over patent infringement (and if so, they lose their license).

In common terms, patents sue for Apache code leads to prohibition to use any other Apache code 😎

@akruis
Copy link

akruis commented Jun 22, 2021

So, this PR is next on my list. :-)

@akruis
Copy link

akruis commented Jun 23, 2021

Hi Kristján,

I updated your pull request. It now uses current HEAD from https://github.com/stackless-dev/stackman. It compiles, but fails to link:

clang -pthread     -Xlinker -export-dynamic -o python Programs/python.o libpython3.8dm.a -lcrypt -lpthread -ldl  -lutil -lm   -lm 
/usr/bin/ld: libpython3.8dm.a(slp_transfer.o): in function `slp_switch':
/home/anselm/src/slp_ws/stackless38//./Include/internal/slp_switch_stackman.h:61: undefined reference to `stackman_switch'
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [Makefile:601: python] Fehler 1

@kristjanvalur
Copy link
Collaborator Author

Yes. The new architecture of 'stackman' uses pre-compiled binaries as a preferred way, to try to eliminate the assembly steps otherwise required. The functions are dead simple and stable and should rarely change, hence are commited in the repo. Target projects, such as stackless, need to link with libstackman and put the proper architecture path in the library search path.
I can have a look at this on the weekend, maybe.

@akruis
Copy link

akruis commented Jun 23, 2021

Ok, that explains a lot.

I have some concerns to depend on pre-compiled software. In my professional work policies make it difficult to integrate pre-compiled open source software into our products. If I use a pre-compiled component, I need a contract with some "vendor" to ensure maintenance and security updates.

@kristjanvalur
Copy link
Collaborator Author

kristjanvalur commented Jun 23, 2021 via email

@akruis
Copy link

akruis commented Jun 24, 2021

I opened #278 to discuss alternative approaches to utilize Stackman.

@kristjanvalur
Copy link
Collaborator Author

It is possible that there is an extra function call level now or something, but I can't remember how these sizes were computed. what units are they?
I would not expect performance to change. The semantics are exactly the same, the only extra cost is perhaps a couple of function calls per switch, which is negligible compared to what is actually done when copying stack data into memory and so on.
The benefit of these calls and callbacks is that the interface remains fixed. Any compiler and linker must respect the ABI and thus the assumptions should all hold.

If we ever move to using "libtealet" however, I would expect differences in performance, in either direction, because there, stack memory management is different. See

@akruis
Copy link

akruis commented Jul 9, 2021

The "make clean" issue is resolved.

Next step: make a plain "./configure" without any arguments work again. Questions:

  • how to decide, if libstackman is required at all?
  • If libstackman is required, which one?

Anselm Kruis added 6 commits July 11, 2021 12:42
We need a way to force a build without stackman. Using the --with-MODULE
mechanism of autoconf we can even configure the location of the Stackman
directory. Move the Stackman directory to Stackless/stackman.
Actually we extract the object files and link the object files, because
this is much simpler to integrate into the Python Makefile.
@akruis
Copy link

akruis commented Jul 11, 2021

On Linux / Unix the patch is now probably OK. On Windows, it is still completely untested. And the changelog entry is still missing.

Anselm Kruis and others added 3 commits July 13, 2021 22:00
You can set the property stackmanDir=no to build without Stackman.
You can set the property stackmanDir=C:\path\to\stackman to build with
Stackman installed in C:\path\to\stackman.
(To set a property add '"/p:name=value"' to the build.bat command line.
<AdditionalDependencies>version.lib;shlwapi.lib;ws2_32.lib;$(stackmanLib)%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories Condition="'$(stackmanLib)'!='' And '$(Platform)'=='x64'">$(stackmanDir)lib\win_x64;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalLibraryDirectories Condition="'$(stackmanLib)'!='' And '$(Platform)'=='Win32'">$(stackmanDir)lib\win_x86;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<ImageHasSafeExceptionHandlers Condition="'$(stackmanLib)'!='' And '$(Platform)'=='Win32'">false</ImageHasSafeExceptionHandlers>
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@kristjanvalur : Currently this is required on x86. Otherwise I get the error message:
stackman.lib(switch_x86_msvc.obj) : error LNK2026: module unsafe for SAFESEH image. [C:\build\stackless38\PCbuild\pythoncore.vcxproj] Creating library C:\build\stackless38\PCbuild\win32\python38_d.lib and object C:\build\stackless38\PCbuild\win32\python38_d.exp C:\build\stackless38\PCbuild\win32\python38_d.dll : fatal error LNK1281: Unable to generate SAFESEH image.[C:\build\stackless38\PCbuild\pythoncore.vcxproj]

@akruis
Copy link

akruis commented Jul 16, 2021

I'll merge this pull request now, because I made good progress with merging C-Python commits (v3.8.0a3) is merged. In my opinion it is better to merge this patch now and fix problems later on.

@akruis akruis merged commit 54ba7b1 into stackless-dev:main-slp Jul 16, 2021
@kristjanvalur
Copy link
Collaborator Author

Hi, I've been on vacation and not following closely.
What does the SAFESEH thing mean? Is there anything we need to do in stackman to better support that?
There is already code in stackman for x86 that saves and restores the SEH state, maybe something is missing (during linking) to signify that?
Can you briefly explain to me how the fix works in the pythoncore.vcxproj ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants