lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


Here is a sample code that causes a crash. I am using Lua 5.2.3.

The crash goes away if I do any one of the 2:

1. Comment out lines 106,107,108 the ones with the string concatenation
2. I change the lua script that I load from the one currently run to the one just above it (where it just has a print)

Any help would be really appreciated




On Sun, Apr 6, 2014 at 8:00 AM, Kevin Martin <kev82@khn.org.uk> wrote:
On 6 Apr 2014, at 15:50, Milind Gupta <milind.gupta@gmail.com> wrote:

>          How should I go about cleanly closing a lua state after a string load error.


Can you write a simple piece of code to demonstrate the problem?

Our product, using Lua 5.2, does this successfully (i.e. error in inner state followed by lua_close of inner state with no app crash), often with 10+ errors daily.

Thanks,
Kevin

#if defined __WIN32__ || defined WIN32
# include <windows.h>
# define _EXPORT __declspec(dllexport)
#else
# define _EXPORT
#endif

#include <stdio.h>
#include <string.h>
#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"


struct scripts
{
	lua_State *L;
	lua_State *T;
};

struct scripts list[4];

static int loadScript(lua_State *L)
{
	short i=0, flag, numSteps;
	const char *code,*iniCode, *err, *msg;
	char fullerr[80];
	list[i].L = luaL_newstate();

	if (NULL == list[i].L)
	{
		lua_pushnil(L);
		lua_pushstring(L,"Cannot initialize Lua State");
		return 2;	// 2 results pushed on the stack
	}


	luaL_openlibs(list[i].L);
	static const struct luaL_Reg TFuncs[] = {
			{NULL,NULL}
	};
	luaL_newlib(list[i].L, TFuncs);
	lua_setglobal(list[i].L,"__ls_");
	lua_getglobal(list[i].L,"__ls_");
	lua_setfield(list[i].L,LUA_REGISTRYINDEX,"__ls_");


	list[i].T = lua_newthread(list[i].L);


    msg = "do"
            "   x=23"
            "end"
            "print(x)";

	msg =   "do"
            "	local coresume = coroutine.resume"
            "	local coyield = coroutine.yield"
            "	local lstep = __ls_"
            "	local function modresume(...)"
            "		coresume(cor)"
            "	end"
            "	local function modyield(...)"
            "		coyield()"
            "	end"
            "	coroutine.resume = modresume"
            "	coroutine.yield = modyield"
            "	__ls_ = nil"
            "end";

    switch(luaL_loadstring(list[i].T,msg))
    {
        case LUA_OK:
            // No error so run the string
            switch(lua_pcall(list[i].T,0,0,0))
            {
                case LUA_OK:
                    // Successfully executed
                    break;
                case LUA_ERRRUN:
                    // Run time error
                case LUA_ERRMEM:
                    // Memory Allocation error
                case LUA_ERRGCMM:
                    // Error Running Garbage collector
                    // Pop the error message
                    msg = lua_tostring(list[i].T,-1);
                    printf("Error: %s",msg);
                    lua_close( list[i].L );
                    list[i].L = NULL;
                    list[i].T = NULL;

                    break;
            }		// switch(lua_pcall(L,0,0,0)) ends here
            break;
        case LUA_ERRSYNTAX:
            // Syntax error, remove the task and clear the slot
        case LUA_ERRMEM:
            // Memory allocation error
        case LUA_ERRGCMM:
            // Error Running Garbage collector
            // Pop the error message
            err = lua_tostring(list[i].T,-1);
            printf("Error message: %s",err);
            msg = "Error loading code:";
strcpy(fullerr,msg);
strcat(fullerr,err);
printf("fullerr: %s",fullerr);
            lua_close( list[i].L );
            printf("L closed");
            list[i].L = NULL;
            list[i].T = NULL;

            break;
    }		// switch(luaL_loadstring(list[i].T,msg)) ends here

	return 0;
}

int _EXPORT luaopen_test(lua_State *L)
{
	static const struct luaL_Reg funcs[] = {
			{"loadScript",loadScript},
			{NULL,NULL}
	};
	luaL_newlib(L, funcs); // Just returns the module as a table
	return 1;
}	// function luaopen_luaStepper ends here