lua-users home
lua-l archive

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


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