Detects the endless loop in the Lua script

Source: Internet
Author: User

Lua is a small and exquisite language, especially suitable for embedding other programs to provide script support for them. However, scripts are usually written by users, and there may be an endless loop. Although this is a user problem, it will cause our host Program to die. Therefore, it is very important to detect the endless loop in the user script and stop the execution of this script.

However, the real problem is that the endless loop is not easy to detect, and some hidden deep endless loops are hard to find, let alone let the machine find them. Therefore, the actual solution is mostly to detect the execution time of the script. If the execution time exceeds a certain limit, it is considered that there is an endless loop. This method is also used in my example below.

The following are some related global variables (I like to use C ++ as a programmer, and I am a loyal fan of C ++. Please be patient.

1 lua_State * g_lua = NULL; // lua Script Engine
2 volatile unsigned g_begin = 0; // time when the script starts to be executed
3 volatile long g_counter = 0; // script execution count, used to determine execution timeout
4 long g_check = 0; // execution count for timeout checks
Run_user_script is used to execute user scripts. It first records the current time to g_begin through GetTickCount. Then add g_counter to the execution, and then add the user script after execution. This ensures that the user script is an odd number while the row is an even number, the code used to detect the script timeout can be used to determine whether the user script is currently being executed. Note that you should use lua_pcall instead of lua_call to call the user script, because the execution of the script will generate an "error" in Lua, which is an exception in C/C ++, only lua_pcall can ensure that this error is correctly handled by the Lua script engine.

1 int run_user_script (int nargs, int nresults, int errfunc)
2 {
3 g_begin = GetTickCount ();
4 _ InterlockedIncrement (& g_counter );
5 int err = lua_pcall (g_lua, nargs, nresults, errfunc );
6 _ InterlockedIncrement (& g_counter );
7 return err;
8}
The following check_script_timeout is used to detect the script timeout and needs to be periodically called in another thread. I don't need to explain the cause. It first records the current script count to g_check, and then checks whether the user script is being executed. If not, it returns the result directly. If yes, it will check how long the script has been executed, when the limit is exceeded, you can use lua_sethook to set a hook function timeout_break. This hook function is called during script execution.

1 void check_script_timeout ()
2 {
3 g_check = g_counter;
4
5 // The user script is not executed and the check does not time out
6 if (g_check & 0x00000001) = 0)
7 return;
8
9 // if the execution time exceeds the set timeout time (1 second), terminate it
10 if (GetTickCount ()-g_begin> 1000)
11 {
12 int mask = LUA_MASKCALL | LUA_MASKRET | LUA_MASKLINE | LUA_MASKCOUNT;
13 lua_sethook (g_lua, timeout_break, mask, 1 );
14}
15}
Finally, it is the hook function. It first removes the hook because it only needs to be executed once. Because the set hook and execution hook are in different threads, and it takes some time from the set hook to the execution hook, therefore, it compares g_check and g_counter to determine whether the script to be executed is still running and time-out. If it is not, it will not do anything, but it will generate an error through luaL_error, stop the execution of the script, and the error will be captured by lua_pcall in run_user_script.

1 void timeout_break (lua_State * L, lua_Debug * ar)
2 {
3 lua_sethook (L, NULL, 0, 0 );
4 // it takes some time for the hook to be set up to run. Therefore, you need to check whether the time-out script is still being executed.
5 if (g_check = g_counter)
6 luaL_error (L, "script timeout .");
7}
The above detection uses two threads, which can be done in one thread and easier. However, this will cause frequent execution of Hook Functions and affect efficiency. You can also use this function if you have no performance requirements.

 

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.