> So really, the whole sequence above should be protected itself by
> another level of lua_pcall, like I described. Am I right?
Right.
Refer to the usage of lua_cpcall() in lua.c.
Also if you are using in a Windows GUI app. you might want to
change the default panic function using lua_atpanic() to
a routine that uses MessageBox() (or whatever). The default
function uses fprintf()/fputs().
db
On 10/15/06, Nick Gammon <nick@gammon.com.au> wrote:
> After recent questions about is it "safe" to use Lua, and a couple of
> application crashes of my own, I am starting to wonder if I have been
> doing it 100% correctly.
>
> There is an example in the PIL book (Listing 24.1) along these lines
> (I have slightly simplified it):
>
> ---------------
> #include "lua.h"
> #include "lauxlib.h"
>
> char buff [] = "print 'hi'";
>
> int main (void)
> {
> lua_State * L = luaL_newstate ();
> luaL_openlibs (L);
> int error = luaL_loadbuffer(L, buff, strlen(buff), "line") ||
> lua_pcall(L, 0, 0, 0);
> return 0;
> } // end of main
> ---------------
>
> Isn't there a problem here? What if luaL_loadbuffer fails? For
> example, out of memory? We can simulate a failure with this example
> program, which in essence does what caused my application to crash
> recently:
>
> ---------------
> #include "lua.h"
> #include "lauxlib.h"
> #include <stdio.h>
>
> int main (void)
> {
> lua_State * L = luaL_newstate ();
> lua_pushnil (L);
> luaL_checkstring (L, -1); --> error, string not on stack
> printf ("Hello, world\n");
> return 0;
> } // end of main
> ---------------
>
> If I run this at the command-line I get this message:
>
> PANIC: unprotected error in call to Lua API (bad argument #-1 (string
> expected, got nil))
>
>
> If I run the equivalent code in my (Windows GUI) application it
> crashes the application with some sort of error in Lua5.1.dll.
>
>
> Would the correct method be to always wrap any attempts to use the
> Lua functions into a protected environment? - like in this example:
>
> ---------------
> #include "lua.h"
> #include "lauxlib.h"
> #include <stdio.h>
>
> // do things here that might fail
> int stub(lua_State *L)
> {
> lua_pushnil (L);
> luaL_checkstring (L, -1);
> }
>
> int main (void)
> {
> lua_State * L = luaL_newstate ();
> lua_pushcfunction (L, stub);
> int error = lua_pcall (L, 0, 0, 0);
> printf ("stub returned %i\n", error);
> printf ("Hello, world\n");
> return 0;
> } // end of main
> ---------------
>
>
> I am familiar with doing lua_pcall to run the code that I ultimately
> want to run in a safe way, but I usually did something like this:
>
> lua_getglobal (L, "somefunction"); --> get some function
> lua_pushstring (L, "blah blah"); --> push arguments to function
> lua_pcall (L, 1, 1, 0); --> call the function
> const char * p = lua_checkstring (L, -1); --> oops! this might fail
>
>
> So really, the whole sequence above should be protected itself by
> another level of lua_pcall, like I described. Am I right?
>
> - Nick
>