Как исправить это переполнение стека в этой комбинации tkinter/exec()/cffi?
У меня есть DSL на питоне, который я выполняю через exec()
, Этот DSL включает вызовы собственных функций через CFFI.
Я получаю переполнение стека (ТАК, вы сделали это неуправляемым!) Сбой при вызове нативной функции, которая всего 2 C вызывает глубоко, только с несколькими uint16_t
s размещены в стеке в каждой функции 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 ответ
Успел соединиться с отладчиком.
Стек, который не имеет ничего после текущего вызова, является признаком того, что стек был перезаписан, обычно через указатель на переменную стека.