[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: SIGSEGV running the GC ?
- From: mnicolet <mnicolet@...>
- Date: Fri, 20 Jun 2003 22:21:02 -0300
Hello list
I am back to lua, reworking luapi to ´true´ 5.0 final, and testing
extensively the suspicious points,
which are what could derive from the two functions I added to lapi.c ...
code follows
////////////////////////
/*
extended api functions for lua 5.0
use with care
*/
#include <luaex.h>
// This is the most important function for the luapi library. It allows most
routines to completely clear
// the stack before return. The lua objects in the stack are stored in host
data structures, which
// may be pushed again later. When the objects are the simple ones, the
usual apis are enough, but
// when dealing with the complex ones, there is no official api, so I
devised this one, which seems
// correct. I would like the word from the lua authors.
// Simply, when dealing with these 3 types, the host program stores the
pointer ( lua_topointer )
// and the type, then when it comes to push again some object, it calls this
function.
// Essentially, it uses the same macros that the _new.... apis do.
// Of course, the correlation between the type and the pointer is warranted.
void lua_pushobject( lua_State * L, void * ptr, int objtype ) {
Udata * u;
switch( objtype ) {
case LUA_TTABLE :
sethvalue( L->top, (Table *) ptr);
break;
case LUA_TFUNCTION :
setclvalue( L->top, ptr );
break;
case LUA_TUSERDATA :
u = (Udata *) ptr;
u -= 1;
setuvalue( L->top, u );
break;
default :
lua_pushliteral( L, "pushobject: improper type\n" );
lua_error( L );
break;
}
// The strange operation with the userdata pointer is the complement of what
lua_topointer does.
api_incr_top( L );
}
// this is a simple cast from a constant pointer to a non constant one
void * lua_toobject( lua_State * L, int index )
{
const void * r = lua_topointer( L, index );
return (void *) r;
}
///////////////////
All the stuff seems to work ... exceptions are some lua scripts when
iterated many times in the same
lua context. I devised a simple method to execute n times a given script, so
forcing the gc lots of
times, and ( I think ) testing near all the lua and luapi code.
But some strange results are scaring me. Some background: to test my
userdata support functions
and policy, I have a ´library´ which registers a userdata which essentially
points to some C structure.
The trick is that the library allows both temporary and static userdata. The
difference is simple:
when allocating the userdata for a static host object, only a pointer is
requested, and made to point
to some of the static instances. These userdata are registered in lua as
globals, so they never becomes
GC´ed. On the other way, whenever a local temporary ( in lua ) is required,
the size requested to lua
is increased by the size of the structure itself and for the ´C´ object
which the structure points to.
So, the __gc metamethod is a curiosity: no resources must be released in the
host data space.
The ´C´ object is a wrapper ( like a variant ) around the basic C objects:
ints, doubles and char strings. As such, some events must be implemented:
__add, __sub, etc
The library exports 6 global userdata, one of which, called Dbl1 is used as
a base for the examples
Two lua scripts exploiting this userdata follows:
Script # 1
-- GC test for user data . based on ud3.lua, less verbose
-- try a variation : wrap the thing in do end - don´t help
do
local a = 20 + Dbl1 - 10
a = a + 5
local b = 30 + Dbl1 - 15
b = b + 10
local c = 40 + Dbl1 - 20
c = c + 15
function show( )
print( "a", a:Tohr( ) )
end
end
Script # 2
-- GC test for user data . based on ud3.lua, less verbose
function doud( )
local a = Dbl1 + 10;
local b = Dbl1 + 20;
local c = Dbl1 + 30;
print( a:Tohr( ), b:Tohr( ), c:Tohr( ) )
end
Tohr is a method like __tostring, nothing fancy.
Using the repeater feature, the script # 2 can be loaded and the function
doud executed 10000
times, without worry. Of course, the __gc metamethod is called lots of times
!!!
But the script # 1 can be iterated ( loading and calling show( ) ) only 24
times, anything more yields a SIGSEGV. Of course, both scripts requires
minimal amounts of memory ( some 140 kb ).
I am very worry, because I cannot discern why the first script fails to
execute an undefined number
of iterations. Even running 15 iterations, the gc is called lot of times !!!
Oh, I must to say that the return value from any arith methods is a fully
allocated userdata of the same
type !!
What is wrong ? Am I missing something ?