Как исправить это переполнение стека в этой комбинации tkinter/exec()/cffi?

У меня есть DSL на питоне, который я выполняю через exec(), Этот DSL включает вызовы собственных функций через CFFI.

Я получаю переполнение стека (ТАК, вы сделали это неуправляемым!) Сбой при вызове нативной функции, которая всего 2 C вызывает глубоко, только с несколькими uint16_ts размещены в стеке в каждой функции C. Приложение Python является tkinter GUI, который вызывает DSL по таймеру (master.after(1000, self.tick)) событие, которое может занять значительную часть самого стека.

Здесь НЕТ рекурсивных вызовов.

OS X 10.12.3, Python 3.6.0rc1 (v3.6.0rc1: 29a273eee9a5, 6 декабря 2016 года, 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 ответ

Успел соединиться с отладчиком.

Стек, который не имеет ничего после текущего вызова, является признаком того, что стек был перезаписан, обычно через указатель на переменную стека.

Другие вопросы по тегам