lua-users home
lua-l archive

Re: lua_close crashing application

[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

AltStyle によって変換されたページ (->オリジナル) /