crash on table.insert call in virtual Lua function called from C++

Willi <[email protected]>
Newsgroups gmane.comp.lang.lua.bind.user
Message-ID <[email protected]>
  Hello,

I just tracked down a crash in my program and was able to reproduce it 
in a simple test program.

I inherit from a C++ class via Lua and overwrite a virtual function. In 
there I call table.insert. If the function is called directly via Lua, 
everything works, but if it is called from C++, i.e. via 
luabind::wrap_base::call(), it crashes. Source code is included.
A workaround is using "myTable[#myTable] = value", I'm going to do that 
for now. (Of course that's not the exact behaviour of table.insert, but 
close enough for my needs.)

So long,
Willi "Mr. Wonko" Schinmeyer

------------------------------------------------------------------------------
The ultimate all-in-one performance toolkit: Intel(R) Parallel Studio XE:
Pinpoint memory and threading errors before they happen.
Find and fix more than 250 security defects in the development cycle.
Locate bottlenecks in serial and parallel code that limit performance.
http://p.sf.net/sfu/intel-dev2devfeb

_______________________________________________
luabind-user mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/luabind-user
main.cpp (text/plain, 2 KB)
//A simple program reproducing a crash I experienced earlier.
// - Willi "Mr. Wonko" Schinmeyer

#include <iostream>
#include <lua.hpp>
#include <luabind/luabind.hpp>
#include <luabind/wrapper_base.hpp>
#include <cassert>
#include <string>
extern "C"
{
#include <lauxlib.h>
}

//I inherit from this class in Lua.
struct myClass
{
    //This is used to call the virtual function from C++
    void CallVirtual(const std::string& foo) { Virtual(foo); }
    //Calling this method directly from Lua works. The parameter isn't necessary to reproduce the crash, it just helps with debug output.
    virtual void Virtual(const std::string& foo) = 0;
};

//Lua wrapper class
struct myClassLua : myClass, luabind::wrap_base
{
    void Virtual(const std::string& foo) { call<void>("Virtual", foo); }
    static void StaticVirtual(myClass& mc, const std::string& foo) { mc.Virtual(foo); }
};

int main()
{
    //initialize
    lua_State* L = lua_open();
    assert(L);
    luaL_openlibs(L);
    luabind::open(L);

    //export via luabind
    luabind::module(L)
    [
        luabind::class_<myClass, myClassLua>("myClass")
            .def(luabind::constructor<>())
            .def("Virtual", &myClass::Virtual, &myClassLua::StaticVirtual)
            .def("CallVirtual", &myClass::CallVirtual)
    ];

    //the lua code
    std::string str = "\
class 'myClassLua' (myClass) \n\
\n\
function myClassLua:__init() \n\
   myClass.__init(self) \n\
end \n\
\n\
function myClassLua:Virtual(foo) \n\
    local tab = {} \n\
    print(foo) \n\
    table.insert(tab, 1) \n\
    print('table.insert called.') \n\
end \n\
\n\
local obj = myClassLua() \n\
obj:Virtual('Works') -- works \n\
obj:CallVirtual('Crashes') -- crashes \n\
print('Didn\\'t crash?') \n\
    ";

    //execute the lua code
    if(luaL_loadbuffer(L, str.c_str(), str.size(), "string")||lua_pcall(L, 0, 0, 0))
    {
        //return != 0 means error.
        //the error is pushed onto the stack.
        std::cout<<lua_tostring(L, -1)<<std::endl;
    }

    return 0;
}
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.