Hello, While porting tarantool to compile with CLang on Linux, an old bug with infinite recursion in LuaJIT on exception reappeared.
The bug manifests itself in the same way as described in https://bugs.launchpad.net/tarantool/+bug/882000 Interestingly, our own test case which Dmitry put up a while ago to detect this bug (luatest.cpp in cmake/) does not catch it. After some trail and error, I was able to come up with a reduced test case, which, when compiled with gcc, works well, and when compiled with clang, breaks with infinite recursion. Let me quote it here (the file is also attached): --------------------------------------------------------------- #include <objc/Object.h> #include <objc/runtime.h> #include "lua.h" #include "lauxlib.h" #include "lualib.h" #include "lj_obj.h" #include "lj_ctype.h" #include "lj_cdata.h" #include "lj_cconv.h" #include "lj_state.h" @interface Exception: Object { char *errmsg; } + (id) alloc; - (id) init: (char*) msg; @end @implementation Exception + (id) alloc { static char buf[sizeof(Exception)]; Exception *new = (Exception *) buf; object_setClass(new, self); return new; } - (id) init: (char*) msg; { self = [super init]; errmsg = msg; return self; } @end void test(struct lua_State *L) { const char *format = luaL_checkstring(L, 1); } static int box_lua_panic(struct lua_State *L) { static int invocation_count = 0; if (invocation_count++ == 0) @throw [[Exception alloc] init: "message"]; abort(); } int main() { lua_State *L = luaL_newstate(); luaL_openlibs(L); lua_atpanic(L, box_lua_panic); @try { test(L); } @catch (Exception *e) { printf("exception handled\n"); } lua_close(L); } ---------------------------------------------------------------------- An example of how it works and breaks: kostja@atlas:~$ clang++ -fobjc-exceptions -I/home/kostja/LuaJIT-2.0.0-beta10/src tarantool_lua.m -L /home/kostja/LuaJIT-2.0.0-beta10/src -lluajit -ldl -lobjc; ./a.out [1] 20790 abort (core dumped) ./a.out kostja@atlas:~$ g++ -fobjc-exceptions -I/home/kostja/LuaJIT-2.0.0-beta10/src tarantool_lua.m -L /home/kostja/LuaJIT-2.0.0-beta10/src -lluajit -ldl -lobjc; ./a.out exception handled kostja@atlas:~$ clang++ -fexceptions -I/home/kostja/LuaJIT-2.0.0-beta10/src tarantool_lua.m -L /home/kostja/LuaJIT-2.0.0-beta10/src -lluajit -ldl -lobjc; ./a.out exception handled Apparently, there are two exception information formats: "right", i.e. the one with which LuaJIT works well, and "wrong", i.e. the one with which LuaJIT breaks. The "right" format happens to be used by default for C++, both by gcc and clang. The "wrong" format is used for Objective C only ,and only for clang: gcc apparently uses the same format both for C++ and gcc exceptions. Another observation is that it doesn't matter how you compile LuaJIT: what matters is how you compile the host program. I'll keep digging why we have this, but this is what I think needs to be done in the meanwhile: - we need to add the above test case to cmake - when building tarantool, even with bundled luajit, we need to be running the test and aborting the build if options are not right. -- http://tarantool.org - an efficient, extensible in-memory data store _______________________________________________ Mailing list: https://launchpad.net/~tarantool-developers Post to : [email protected] Unsubscribe : https://launchpad.net/~tarantool-developers More help : https://help.launchpad.net/ListHelp

