Source: python-greenlet Severity: important Tags: upstream patch The 0.3.1 version of python-greenlet does not seem to behave on armhf. The following code will show the problem:
from greenlet import greenlet def test1(): print 12 gr2.switch() print 34 def test2(): print 56 gr1.switch() print 78 print 'Correct answer is:' print '12' print '56' print '34' print 'Actual answer is:' gr1 = greenlet(test1) gr2 = greenlet(test2) gr1.switch() However, the 0.3.3 version will not compile, either. So, the attached patch (sorry, not my best work ever ... I'm in a hurry) does two things: (1) add -fomit-frame-pointer to the compile so that r7 can actually be saved, and (2) changes platform/switch_arm32_gcc.h to incorporate the latest upstream changes (which were insufficient) and be more conversative in what gets saved on task switch. With the changes, 0.3.3 builds on armhf and passes the test suite with no errors.
Index: python-greenlet-0.3.3/setup.py =================================================================== --- python-greenlet-0.3.3.orig/setup.py 2012-02-08 18:34:38.000000000 +0000 +++ python-greenlet-0.3.3/setup.py 2012-04-27 21:34:57.000000000 +0000 @@ -7,6 +7,10 @@ if sys.platform == "openbsd4" and os.uname()[-1] == "i386": os.environ["CFLAGS"] = ("%s %s" % (os.environ.get("CFLAGS", ""), "-Os")).lstrip() +# workaround segfaults on ARMv7 +if sys.platform == "linux2" and os.uname()[-1] == "armv7l": + os.environ["CFLAGS"] = ("%s %s" % (os.environ.get("CFLAGS", ""), "-fomit-frame-pointer")).lstrip() + try: from setuptools import setup, Extension setuptools_args = dict(test_suite='tests.test_collector', zip_safe=False) Index: python-greenlet-0.3.3/platform/switch_arm32_gcc.h =================================================================== --- python-greenlet-0.3.3.orig/platform/switch_arm32_gcc.h 2012-02-08 18:34:38.000000000 +0000 +++ python-greenlet-0.3.3/platform/switch_arm32_gcc.h 2012-04-27 21:40:55.000000000 +0000 @@ -25,7 +25,20 @@ #ifdef SLP_EVAL #define STACK_MAGIC 0 -#define REGS_TO_SAVE "r4", "r5", "r6", "r7", "r8", "r9", "lr" +#define REGS_TO_SAVE_GENERAL "r4", "r5", "r6", "r7", "r8", "r9", \ + "r10", "r11", "ip", "sp", "lr", "pc" +#if defined(__SOFTFP__) +#define REGS_TO_SAVE REGS_TO_SAVE_GENERAL +#elif defined(__VFP_FP__) +#define REGS_TO_SAVE REGS_TO_SAVE_GENERAL, "d8", "d9", "d10", "d11", \ + "d12", "d13", "d14", "d15" +#elif defined(__MAVERICK__) +#define REGS_TO_SAVE REGS_TO_SAVE_GENERAL, "mvf4", "mvf5", "mvf6", "mvf7", \ + "mvf8", "mvf9", "mvf10", "mvf11", \ + "mvf12", "mvf13", "mvf14", "mvf15" +#else +#define REGS_TO_SAVE REGS_TO_SAVE_GENERAL, "f4", "f5", "f6", "f7" +#endif static int slp_switch(void) @@ -33,8 +46,8 @@ void *fp; register int *stackref, stsizediff; __asm__ volatile ("" : : : REGS_TO_SAVE); - __asm__ volatile ("str fp,%0" : "=m" (fp)); - __asm__ ("mov %0,sp" : "=g" (stackref)); + __asm__ volatile ("mov r0, fp\n\tstr r0, %0" : "=m" (fp) : : "r0"); + __asm__ ("mov %0,sp" : "=r" (stackref)); { SLP_SAVE_STATE(stackref, stsizediff); __asm__ volatile ( @@ -45,9 +58,9 @@ ); SLP_RESTORE_STATE(); } - __asm__ volatile ("ldr fp,%0" : : "m" (fp)); + __asm__ volatile ("ldr r0, %0\n\tmov fp, r0" : : "m" (fp) : "r0"); __asm__ volatile ("" : : : REGS_TO_SAVE); return 0; } -#endif \ No newline at end of file +#endif