lua-users home
lua-l archive

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


Hi all,

I have some code for test luajit's ffi.gc(), if loop count is low, it's
all right, but if loop count is big enough, luajit will crash. I have
attached the code here (c++ & lua) and the code do something like this:
//test.cpp
struct point { int x,y; };
point* newpt(){ return new point; }
void delpt(point* p){ delete p; }

struct fmem {
point* (*newpt)();
void (*delpt)(point*);
} s_fmem = { &newpt, &delpt };

fmem* getfmem(){ return &s_fmem; }

and then in lua code we get fmem pointer through ffi and then do test
like this:
--test.lua
local fmem = ffi.C.getfmem()
for i=1, 100 do
local pt = fmem.newpt()
ffi.gc(pt, fmem.delpt)
end --loop 100 times is ok in my machine

for i=1, 10000000 do
local pt = fmem.newpt()
ffi.gc(pt, fmem.delpt)
end --crash! or get error messages "PANIC: unprotected error in call to
Lua API (wrong number of arguments for function call)"

And my test machine is running archlinux i686,:
$ uname -a
Linux archbook 2.6.37-ARCH #1 SMP PREEMPT Tue Mar 8 08:08:06 UTC 2011
i686 Intel(R) Core(TM) i7-2630QM CPU @ 2.00GHz GenuineIntel GNU/Linux
$ g++ -v
Using built-in specs.
COLLECT_GCC=g++
COLLECT_LTO_WRAPPER=/usr/lib/gcc/i686-pc-linux-gnu/4.5.2/lto-wrapper
Target: i686-pc-linux-gnu
Configured with: /build/src/gcc-4.5-20110127/configure --prefix=/usr
--enable-languages=c,c++,fortran,objc,obj-c++,ada --enable-shared
--enable-threads=posix --enable-__cxa_atexit --enable-clocale=gnu
--enable-gnu-unique-object --enable-lto --enable-plugin --enable-gold
--with-plugin-ld=ld.gold --disable-multilib --disable-libstdcxx-pch
--with-system-zlib --with-ppl --with-cloog
--with-cloog-include=/usr/include/cloog-ppl --libdir=/usr/lib
--libexecdir=/usr/lib --mandir=/usr/share/man --infodir=/usr/share/info
Thread model: posix
gcc version 4.5.2 20110127 (prerelease) (GCC)

compile options is :
$ g++ -o test test.cpp -Wl,-E -lluajit-5.1
and luajit is release shared lib.

Best,
Zhu Ya Dong
#include <lua.hpp>
#include <cstdlib>
#include <cassert>
struct point
{
    int x,y;
};
static point* newpt()
{
    point* p = new point;
    assert(p);
    return p;
}
static void delpt(point* p)
{
    delete p;
}
struct fmem
{
    point* (*newpt)();
    void (*delpt)(point*);
};
static fmem s_fmem = {&newpt, &delpt};
extern "C"
{
    fmem* getfmem(){ return &s_fmem; }
}

int main(int argc, char **argv)
{
    if (argc < 2) 
        exit(printf("give a lua file as argument."));
    lua_State* L = lua_open();
    luaL_openlibs(L);
    if (luaL_dofile(L, argv[1]))
        lua_error(L);
    return 0;
}
local ffi = require'ffi'
ffi.cdef[[
typedef struct point{int x,y;};
typedef struct fmem
{
    struct point* (*newpt)();
    void (*delpt)(struct point*);
};
struct fmem* getfmem();
]]
local c = ffi.C
local fmem = c.getfmem();
for i=1,10 do
    local pt = fmem.newpt()
    ffi.gc(pt, fmem.delpt)
end
print('test count=10 OK.')
for i=1,10000000 do 
    local pt = fmem.newpt()
    ffi.gc(pt, fmem.delpt)
end
print('test count=10000000 OK.')