[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Problems with MinGW v3.4.5 on WinXP SP2 when luaL_checkxxx() fails
 
- From: "RJP Computing" <rjpcomputing@...>
 
- Date: Tue, 31 Jul 2007 18:32:04 -0400
 
Hi all,
WARNING: Long winded email coming up.
My system is Windows XP SP2 with MinGW 5.1.2/gcc v3.4.5 and Lua 5.1.2. I am not sure if this is a Lua issue or a lack of understanding on my part, so please bare with this. Thanks.
I am getting a SIGSEGV fault and I can't explain it. When I call a cfunction with a incorrect parameter and I use luaL_checkxxx() functions on the variable I am getting a SIGSEGV error. If you look at the lLog() function in the example below you can see my comment about making the variable static. Why is this needed? What principle am I missing? I feel kind of silly asking a C++ish question, but I think I am actually having a problem with the interaction between Lua and C++. The issue shows when the exception is thrown from the throw_errors() function, when the stack is unwinding.
I worked up an example. Sorry it is a bit big but it shows the problem involves exceptions: 
(I used the binary static library from LuaBinary on LuaForge [
http://luaforge.net/frs/download.php/2239/lua5_1_2_Win32_mingw3_lib.zip])
<code - main.cpp>
#include <iostream>
#include <string>
#include <exception>
#include "lua.hpp
"
namespace lua
{
    /** A generic lua exception.
     */
    class exception : public std::exception
    {
    public:
        /// Constructor.
        exception() : std::exception() { }
        /// Constructor.
        explicit exception( const char* desc ) : std::exception(), description( desc ) { }
        virtual ~exception() throw() { }
        /** Get a description of the error.
         * @returns a C-string describing the error
         */
        virtual const char* what() const throw()
        {
            return description.c_str();
        }
    private:
        std::string description;
    };
    int throw_error( lua_State* luaState, int code )
    {
        const char* error;
        // below, we package lua errors into exceptions
        if ( code != 0 )
        {
            error = lua_tostring( luaState, -1 );
            lua_pop( luaState, 1 );
            throw exception( error );
        }
        return code;
    }
}
static int lLog( lua_State* luaState )
{
    //static 
    std::string val; // <- by not declaring this static I can't unwind the stack.
    size_t l;
    // Get the function argument and also check it.
    const char* c = luaL_checklstring( luaState, 1, &l );
    // Assign the string to a standard string.
    val.assign( c, l );
    // Call the real function.
    std::cout << "[DEBUG] " << val << std::endl;
    return 0; // number of return values
}
int main( int argc, char* argv[] )
{
    // Check for commandline arguments.
    if ( argc < 2 )
    {
        std::cerr << "Requires a script file passed to the executable" << std::endl;
        return 1;
    }
    try
    {
        // Create a new Lua state.
        lua_State* L = luaL_newstate();
        if ( L != NULL )
        {
            // opens all the Lua libraries.
            luaL_openlibs( L );
            // register test function.
            lua_register( L, "log", lLog );
            // Load the script.
            luaL_loadfile( L, argv[1] );
            // Run the script.
            lua::throw_error( L, lua_pcall( L, 0, 0, 0 ) );
            // Close the Lua state.
            lua_close( L );
        }
        else
            return 1;
    }
    catch( lua::exception& ex )
    {
        std::cerr << ex.what() << std::endl;
    }
    std::cout << "Finshed test..." << std::endl;
    return 0;
}
<endcode - main.cpp>
<code - test.lua>
log( "Script entered" )
print( "This is a test to see if the lua_checklstring() function fails" )
print( "and recovery is possible." )
-- Call 'log()' with no parameter to make sure check fails.
log( )
log( "Script exited" )
<endcode - test.lua>
-- 
Regards,
Ryan
RJP Computing