Lua: Could this cause segfault

I am developing a program that uses Lua to create scripts, and sometimes it will crash. With GDB, I think I found the problem, but I don’t know if it solved it, since segfault will only happen sporadically. So the old code was as follows:

void Call(std::string func){ lua_getglobal(L, func.c_str()); //This is the line GDB mentioned in a backtrace if( lua_isfunction(L,lua_gettop(L)) ) { int err = lua_pcall(L, 0, 0,0 ); if(err != 0){ std::cout << "Lua error: " << luaL_checkstring(L, -1) << std::endl; } } } 

The fact is that this function will be called several times per second, but the function to be called is not always defined, so I thought the stack would overflow. I added the following line:

 lua_pop(L,lua_gettop(L)); 

And segfault is no longer happening. Could this be a problem?

+6
source share
2 answers

Using lua_gettop(L) as an argument to lua_pop will clear the entire Lua API stack (this is equivalent to lua_settop(0) ), which is probably not what you want. But actually your problem is that lua_getglobal always pushes something; if the global with the given name does not exist, it pushes nil , as does the equivalent Lua expression. However, lua_pcall a function and all arguments (if any, you specified zero in your case), so you won't get a problem if the function exists. What you need to do is add lua_pop(L, 1) to the else clause of the external if . This way your function will always be balanced (i.e. Leave the stack as it is).

You can see these things in the Lua manual: for each function, this is indicated in the description, and also indicated in gray, in brackets next to the function prototype. For example, lua_getglobal has [-0, +1, e], which means that it will not call any elements and (always) click one element (and e means that this can cause errors).

+5
source

According to www.lua.org/manual/5.2/manual.html#4.2 , you are responsible for maintaining the stack since Lua does not perform any checks. I would suggest that segfault is a reasonable result of not keeping the stack clean (new values ​​are moved to a memory location outside the actual space of the stack and, by chance, also outside your virtual process memory).

Since you are not calling lua_pcall to remove a non-function from the stack, this will increase the stack indefinitely.

Your solution should work if the called function does not leave something on the stack. Since you set nresults to 0, Lua does not leave any results on the stack.

My understanding of the lua_pcall link is that error codes can be left on the stack even if nresults is 0. Edit: I also checked this behavior, and it is exactly the same as I expected.

In this case, calling lua_gettop at the beginning and lua_settop in the end will work anyway and balance your stack.

+1
source

Source: https://habr.com/ru/post/974752/


All Articles