lua-users home
lua-l archive

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


Hello
Sorry, my apologies. I found why the host program SIGSEGV´ed running the
first script and not
the second. It may be of interest to some one. The main difference between
the scripts is the
´density´ of temporary userdata. Note that #1 executes lots of arithmetic on
every local but not so
the second script. Every operation involves a new temporary userdata.
Some additional explanation is required.
My ´policy´ towards userdata creation is that one luapi_ function obtains an
´object´ of the required
size from lua, and returns a reference to it ( in fact, the pointer )
popping the stack. The creation process completes later by calling a second
routine, which pushes again the previously obtained object, its metatable
( another opaque reference ) and calls lua_setmetatable to bind both.
This two step udata creation seemed useful because in the interim, being the
stack ´empty´ the host could call any lua function at leisure. And that was
my library do. Even if the first function ( udata allocation ) is called
from a unique routine, the second is called at least from three other. So,
every function must obtain a ´pointer´ to the metatable just before invoking
the binder function. But exactly that was the origin of the crash running
the devil script. Detail: the metatable is stored in the registry, keyed by
the ´userdata type name´. Of course, to get it, one must push a string
into the stack. In turn, lua_pushlstring calls the garbage collector (
because the macro can determine
we are not executing a function ). My conclusion is that being the newly
allocated userdata chunk
unreferenced ( assuming that the stack is one of the possible refereces a
collectable object may have ) and the gc ´more urged´, it collected my
newborn userdata, and I finished with a pointer
to free memory ( in fact, tracing the address where the SIGSEGV happened, it
pointed to the most
low level MM module of the C library ).
The cure was simple: every function that requires a metatable reference, get
it before invoking the
first step allocator, so the GC is  not invoked. This restriction render
near useless the two step scheme, but validates all the rest of the
concepts, specifically the api extension code I posted yesterday.
Regards
----- Original Message -----
From: "mnicolet" <mnicolet@satlink.com>
To: "lista lua" <lua@bazar2.conectiva.com.br>
Sent: Friday, June 20, 2003 10:21 PM
Subject: SIGSEGV running the GC ?


> Hello list
> I am back to lua, ........ the suspicious points ........
> 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
>
> But the script # 1 can be iterated ( loading and calling show( ) ) only 24
> times, anything more yields a SIGSEGV. Of course, both scripts requires