lua+luabind, no error information at top of stack, after "runtime error"

1.2k Views Asked by At

I'm trying to embed lua into my game engine. It all worked good until now. I started registering functions to interface with the game engine (e.g. move_object(id, x, y)), and the registration worked fine. Next, I tried to use it like this:

handlers={}

handlers["update"] = function(objId)
--  print(objId)
    move_object(objId, 0, 0)
end

This gives me a "runtime error" exception from luabind. I searched everywhere, and according to the internet (and the luabind source), the error message should still be at the top of the lua stack. I tried catching the luabind::error, and printing the top of the stack both like this:

std::cout << "error: lua: " << lua_tostring(exc.state(), -1) << std::endl;

and like this:

std::cout << "error: lua: " << luabind::object(luabind::from_stack(exc.state(), -1)) << std::endl

and both print this:

error: lua: update

which I assume is simply the last value pushed when I called the update function from the handlers table. This value should have been overwritten, upon encountering an error, with the detailed error string, correct? According to the luabind source file "error.hpp" at the definition of class error :

// this exception usually means that the lua function you called
// from C++ failed with an error code. You will have to
// read the error code from the top of the lua stack
// the reason why this exception class doesn't contain
// the message itself is that std::string's copy constructor
// may throw, if the copy constructor of an exception that is
// being thrown throws another exception, terminate will be called
// and the entire application is killed.

I believe the problem with my lua code is actually with the registration of my move_object function (the update function runs. I know this, because I have uncommented that print call before), but I cannot be sure without some better error information! Haha

I fixed the error, if it is of any help. I was defining the move_object function like so:

luabind::module(m_L)[
    luabind::def("move_object", &ScriptEntityManager::move_object)
];

but apparently, you cannot define static member functions as regular functions with luabind. I changed it to this (made move_object a regular global function in C++):

luabind::module(m_L)[
    luabind::def("move_object", move_object)
];

I don't know if that helps with the original problem or not, but I figured more information couldn't hurt! :)

1

There are 1 best solutions below

0
On

I also get a wrong value for the error message when catching a luabind exception. I've solved the problem by setting the error handler used by luabind (set_pcall_callback) so that it prints the error (and the callstack), which happens before the exception is thrown. It works fine for me that way.

But if someone actually knows why the top of the stack does not contain the error message when catching the exception, I'm interested too :-)

Here is the error handler I use in case it can help someone (where "print" is some custom function that can log an std::string):

int luabindErrorHandler( lua_State* L )
{
    // log the error message
    luabind::object msg( luabind::from_stack( L, -1 ) );
    std::ostringstream str;
    str << "lua> run-time error: " << msg;
    print( str.str() );

    // log the callstack
    std::string traceback = luabind::call_function<std::string>( luabind::globals(L)["debug"]["traceback"] );
    traceback = std::string( "lua> " ) + traceback;
    print( traceback.c_str() );

    // return unmodified error object
    return 1;
}