如何修复此tkinter / exec()/ cffi组合中的堆栈溢出?

时间:2017-02-17 18:54:23

标签: python python-cffi python-exec

我有一个Python驱动的DSL,我通过exec()执行。此DSL包含通过CFFI的本机函数调用。

当调用一个只有2个C调用深度的本机函数时,我发现堆栈溢出(SO,你让它无法访问!)崩溃,只有少量uint16_t分配在堆栈中每个C函数。 Python应用程序是一个tkinter GUI,通过计时器(master.after(1000, self.tick))事件调用DSL,这可能占用了很大一部分堆栈。

此处没有递归调用。

OS X 10.12.3,Python 3.6.0rc1(v3.6.0rc1:29a273eee9a5,2016年12月6日,16:24:13),CFFI 1.9.1

我知道resource.setrlimit(resource.RLIMIT_STACK, (resource.RLIM_INFINITY, resource.RLIM_INFINITY)),但它需要超级用户权限。我认为这不是必需的,因为只有两个函数调用的剩余堆栈是不正常的。

CFFI或exec()是否可以限制被调用者的堆栈大小?

从DSL调用函数:

ffi_builder.cdef('''
//...
int FooNode_SetProperty(struct FooNode *pThis, const char *szPropertyName, int nValue);
''')

def set_channel(node, channel):
    node.SetProperty(b'channel', channel)

exec调用代码:

    self._globals = {
        '__builtins__': __builtins__,  
        # https://docs.python.org/3/library/functions.html#eval "If the globals dictionary is present and lacks
        # ‘__builtins__’, the current globals are copied into globals before expression is parsed."

        'run': {
            'duration': 60 * MICROS,
            'success': None
        },

        'set_channel': set_channel,
        'turn_off': turn_off,
        'turn_on': turn_on,
        'finish': finish,
        # 6 more functions here
    }

    exec(event_text, self._globals, {})

Apple报道:

Crashed Thread:        0  Dispatch queue: com.apple.main-thread

Exception Type:        EXC_CRASH (SIGABRT)
Exception Codes:       0x0000000000000000, 0x0000000000000000
Exception Note:        EXC_CORPSE_NOTIFY

Application Specific Information:
[35633] stack overflow

Thread 0 Crashed:: Dispatch queue: com.apple.main-thread
0   libsystem_kernel.dylib          0x00000001003bfdd6 __pthread_kill + 10
1   libsystem_pthread.dylib         0x00007fffe03dc787 pthread_kill + 90
2   libsystem_c.dylib               0x00007fffe02564bb __abort + 140
3   libsystem_c.dylib               0x00007fffe0256d7e __stack_chk_fail + 205
4   libmush_real.dylib          0x0000000104c4d714 send_counters_report_request + 532

(这个帖子真的在这里结束,Apple报告中没有其他内容)

1 个答案:

答案 0 :(得分:0)

管理与调试器连接。

当前调用之后没有任何内容的堆栈是堆栈被覆盖的标志,通常是通过指向堆栈变量的指针。