🎉 Celebrating 25 Years of GameDev.net! 🎉

Not many can claim 25 years on the Internet! Join us in celebrating this milestone. Learn more about our history, and thank you for being a part of our community!

gracefully handling lua foulness..

Started by
22 comments, last by nekoflux 20 years, 4 months ago
so...looking at the documentation, I can throw a try{}catch{} block around any of the c++ code that invokes lua?

will this be sufficient?
nekoflux
Advertisement
yes, as long as you have it catch teh right exception, then you can deal with the problem gracefully
It doesnt seem to work for me.

Heres my code:

//lua callbacksvoid CSimulation::entrypoint_callback(lua_State* L){    try{	    	  // the function name 	  lua_getglobal(L, "init");	  lua_call(L,0,0);	}	catch(luabind::error& e)	{	  lua_State* L = e.state();		// L will now point to the destructed		// lua state and be invalid		/* ... */		MessageBox(NULL, "error trapped from lua", "Simulation Error", MB_OK); 	}	catch(luabind::cast_failed& e)	{		lua_State* L = e.state();		// L will now point to the destructed		// lua state and be invalid		/* ... */		MessageBox(NULL, "cast error trapped from lua", "Simulation Error", MB_OK); 	}}



In the above code, I trap for luabind::error and luabind::cast_failed.

now heres my lua script that i test it with:
function init( )   --this line ought to muck things up nice n proppa ;)     thiswillcrashmyengine   end

when I run my engine it still crashes, and I never see either dialog box come up ("error trapped from lua" or "cast error trapped from lua")

which leads me to believe its not catching the error at all.
Any thoughts?

neko...
nekoflux
That code would be crashing before you even got to that function. Syntax errors occur when you load or compile a script, not when you execute it.

Show us the code where you load that script in.

"Sneftel is correct, if rather vulgar." --Flarelocke
I havn''t used lua but I am planning to use it in my engine so I can''t say I know exactly what the problem you are experiencing. But I went online to just do a little searching since I was going to be using lua eventually too.

according to this site:
http://www.fensende.com/Users/mcuddy/ltn/luapp.html

looking at the code they have this extern c function

extern "C" void luaD_breakrun (lua_State *L, int errcode) {
throw lua_exception(errcode);
}

maybe you need to include this in your code so that lua can give an exception?

also I don''t know if this is helpful, from http://lua-users.org/wiki/LuaFaq:

"Lua isn''t working with my C++ program! Why am I getting compiler and linker errors?
Lua indeed works with C++. You need to extern "C" the Lua header files since they are ANSI C headers. See the next FAQ and BuildingLua.

I''m getting segfaults when I run my Lua script. Why doesn''t Lua catch the errors?
Lua does not verify that API calls have correct arguments. You have probably corrupted the stack, referenced an invalid stack index, or pushed too many things on the stack (see luaL_checkstack()). Enable api checking while you are debugging; see this message for instructions:"


Keep us posted if you find the answer.
~Wave
in this case it appears to be that he isnt catching the error in the right place

Thing is, when i was having ''issues'' with luabind and bad scripts the debugger was catching the exception and letting me break out to see where the problem was... (well, I had to look at the stack trace to find the point i called it, but the idea stands)
sneftel, im not sure thats entirely true. Consder my function slightly modified:
void CSimulation::entrypoint_callback(lua_State* L){    try{	    	  // the function name           MessageBox(NULL, "stub A", "Error", MB_OK); 	  lua_getglobal(L, "init");          MessageBox(NULL, "stub B", "Error", MB_OK); 	  lua_call(L,0,0);          MessageBox(NULL, "stub C", "Error", MB_OK); 	}	catch(luabind::error& e)	{	  lua_State* L = e.state();		// L will now point to the destructed		// lua state and be invalid		/* ... */		MessageBox(NULL, "error trapped from lua", "Simulation Error", MB_OK); 	}	catch(luabind::cast_failed& e)	{		lua_State* L = e.state();		// L will now point to the destructed		// lua state and be invalid		/* ... */		MessageBox(NULL, "cast error trapped from lua", "Simulation Error", MB_OK); 	}}


when I start my engine and execute the script, I see "Stub A". Then I click ok, and I see "Stub B", then click ok, and my engine dies. So between "Stub B" and "Stub C" it crashes, and the only call between them lua_call(L,0,0);



anyways, here is the code that calls the above function.
	// load the init callback script 	lua_dofile(luaVM, "init.lua");      	// execute the init() callback 	 entrypoint_callback(luaVM);


Note: I already tried wrapping the above to calls in he same try{}catch{} block I use in my entrypoint_callback function defined above.

heeelp!
nekoflux
Of course it does. You're not listening. Reread my above posts.

Point 1: Lua will correctly and gracefully signal runtime errors in Lua scripts. LuaBind will handle this by throwing exceptions.

Point 2: Lua will not gracefully handle errors that arise from bugs in the C/C++ side.

Point 3: Syntax errors are signaled at the time of loading.

Here's what's happening, in your case:

Step 1: you load up the script with lua_dofile. During the loading process, a syntax error is encountered. lua_dofile doesn't execute anything (in particular, it doesn't set the global init), and it returns LUA_ERRSYN (Point 3). You fail to check for this.

Step 2: you execute lua_getglobal to get init. Since init was never set, this causes nil to be pushed on the stack.

Step 3: you execute lua_call, which expects a function to be on top of the stack. However, you haven't given it one. Crashing ensues. (Point 2)

The problem is clear: you're not doing enough error checking. Lua can't catch all possible programmer errors, and for the sake of performance it doesn't try to. If you don't _ABSOLUTELY KNOW_ that something like lua_dofile or lua_getglobal will succeed, check for it and handle failure gracefully. (hint: you could throw an exception.)

"Sneftel is correct, if rather vulgar." --Flarelocke

[edited by - sneftel on March 2, 2004 2:42:03 AM]

[edited by - sneftel on March 2, 2004 2:42:23 AM]
I had similar problems with crashes in C++ code. This occured whenever there were a syntax error in the script. This was related to LUA using stdout, stderr streams that was not open in my application. Problem was solved after following the directions in this thread however:

http://www.ogre3d.org/phpBB2/viewtopic.php?t=2433&postdays=0&postorder=asc&highlight=lua&start=25

Steps:
- Registering a custom error handler
- Reassigning _OUTPUT and _INPUT


[edited by - Borundin on March 2, 2004 9:38:45 AM]

[edited by - Borundin on March 2, 2004 9:41:31 AM]
Sneftel, I did read your posts. If you read the last comment in my last post, I mention that I already tried wrapping the lua_dofile() function in the try{}catch{} block as shown in the luabind documentation.

But Im still confused because when I wrap a try catch block around lua_dofile() it never executes the catch. Here:

try{  lua_dofile(luaVM, "init.lua");   // execute the init() callback    entrypoint_callback(luaVM);}catch(luabind::error& e){  lua_State* L = e.state();  // L will now point to the destructed  // lua state and be invalid  /* ... */  MessageBox(NULL, "error trapped from lua", "Simulation Error", MB_OK); }	}


now, in the above code, why isnt it firing the catch block? init.lua clearly contains code that is not of proper syntax...

thanks for your patience!

neko
nekoflux

This topic is closed to new replies.

Advertisement