lua底层没有提供检查死循环的接口, 在不影响性能的情况下, 比较可行的方法是检测脚本执行时间, 超过一定的时限, 就认为存在死循环
多线程下, 可以在其他线程中监测是否存在执行时间异常的脚本, 单线程下就会麻烦一点
这里提供一种单线程下的死循环检查方法, 通过lua_sethook跟signal来解决死循环问题
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
| static void lstop (lua_State * L, lua_Debug * ar) { (void)ar; lua_sethook(L, NULL, 0, 0); luaL_error(L, "There may be an endless loop !"); } static void laction (int i) { signal(i, SIG_DFL);
lua_sethook(L, lstop, LUA_MASKCALL | LUA_MASKRET | LUA_MASKCOUNT, 1); } void run(const char * path) { L = luaL_newstate(); luaL_openlibs(L); luaL_checkversion(L);
int result = luaL_loadfile(L, path); if (result != 0) { const char * error = lua_tostring(L, -1); _EXIT_("Load lua file [%s] failed, error : %s\n", path, error); }
alarm(5); signal(SIGALRM, laction); result = lua_pcall(L, 0, 0, 0); alarm(0); signal(SIGALRM, SIG_DFL);
if (result != 0) { const char * error = lua_tostring(L, -1); _EXIT_("Call lua failed, error : %s\n", error); }
_EXIT_("Exit the lua VM\n"); }
|
1 2 3 4 5 6
| function main() local loop = true while loop do end end main()
|
启动测试, 5s后可以看到死循环被中断了
1
| Call lua failed, error : script.lua:6: There may be an endless loop !
|