私はexec()
で実行するPythonで動くDSLを持っています。このDSLには、CFFIを介したネイティブ関数呼び出しが含まれています。このtkinter/exec()/ cffiの組み合わせでこのスタックオーバーフローを修正する方法はありますか?
ちょうど2 Cで深刻なネイティブ関数を呼び出すときに、スタックオーバーフローが発生しているので、各C関数のスタックにuint16_t
が割り振られています。 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日、午後04時24分13秒)、CFFI 1.9.1
私はresource.setrlimit(resource.RLIMIT_STACK, (resource.RLIM_INFINITY, resource.RLIM_INFINITY))
の承知しているが、それスーパーユーザー特権が必要です。 2つの関数呼び出しのためにスタックが残っているのは普通ではないので、これは必要ないと思います。
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, {})
アップルのレポートピース:(このスレッドは本当にここで終了
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
、アップルでは他には何も報告書)