[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: module loading in C
 
- From: Hans van der Meer <H.vanderMeer@...>
 
- Date: Thu, 4 Sep 2008 12:25:36 +0200
 
I received two reactions, thanks.
Luiz Henrique de Figueiredo wrote:
> I have module A loaded from a lua program wth require, while >  
submodules A1, A2, .. are loaded by A on demand.
It seems easier to me to add the submodules to package.preload.
I cannot see how, because the loading is dynamic. It is not known  
beforehand what submodules will be present and their number may vary.
David Burgess wrote:
My bet is that you have a modified Global thread environment. If you  
have called require() beforehand it is loaded into the master global  
environment and the _G.package table. When calling your function,  
are these two references being created in "your" LUA_GLOBALSINDEX or  
the master one?
Indeed I had in the main module:
lua_newtable(L); /* table for C-function environment */
lua_replace(L, LUA_ENVIRONINDEX); /* set it */
But removing these did not make he problem go away.
I tried various other things like also putting the loaded module table  
inside a "loaded"-table in the LUA_ENVIRONINDEX table. Nothing helped.
Some more experiments were made in the hope they will provide enough  
information for someone to pinpoint the cause of the problem. Putting  
prints in Lua's loadlib.c shows the following sequence of events just  
before a crash (segmentation fault):
(just before this iom-close was called successfully)
>>>> gctm called for 0x107350 <<<<<
>>>> ll_unloadlib LUA_DL_DLOPEN 0x107350 <<<<
TRACE: entering <io_gc> in module ioio
TRACE: io_gc called for readtest.txt.mem
TRACE: entering <close> in module ioio
TRACE: package 'iom' is loaded
TRACE: calling subsystem iom for close
Segmentation fault
0x107350 is the address of the module 'iom' in which the close  
function should be called. As can be seen, by that time the module is  
already unloaded.
All this occurs in the last phase of the program execution, where  
apparently the garbage collector is removing all leftovers. In this  
case for userdata 'readtest.txt.mem' the __gc function is entered and  
the close function in the iom submodule called for it.
The line "TRACE: package 'iom' is loaded" comes from querying the  
LUA_ENVIRONINDEX-table where the iom module table is put into and  
still appears to be at that point.
QUESTION:
I suspect that the cleanup of the garbage collector (in the last phase  
of execution) occurs in the order in which the objects are  
encountered. If so, it is detrimental if the order of unloading is  
critical, as is the case here.
I expected that the parent module ioio (not yet unloaded) and having  
the iom table in its environment, would prevent early unloading even  
in the final cleanup; clearly that is not true. However, I fail to see  
why the iom module could be marked eligible for gc'ing while still  
held by its parent ioio? Is the library perhaps some other object than  
the table granting access to it? I am not versed enough in matters of  
library loading to answer that question.
Is my analysis correct?
Is there a way to solve this?
Thanks in advance for taking your time in replying.
Hans van der Meer
On 2 sep 2008, at 22:46, Hans van der Meer wrote:
I am wrestling with keeping modules from crashing(disappearing?).
I have module A loaded from a lua program wth require, while  
submodules A1, A2, .. are loaded by A on demand. The code for the  
submodule loading:
lua_getglobal(L, subsystem); /* char *subsystem */
if (lua_isnil(L, -1)) {
   lua_pop(L, 1); /* pop the nil */
   lua_getglobal(L, "require");  /* setup call to require */
   lua_pushstring(L, subsystem); /* argument is name of module to  
load */
   if (lua_pcall(L, 1, 1, 0)) luaL_error(L, "require failed");
}
If I have in the Lua program a statement:
subsys = require "A1"
before the programmatic loading will occur all is well, leave it out  
and the program may crash when trying to enter a function in the  
submodule A1. This occurs in the endgame of the program execution.  
This follows from the fact that putting an offending operation  
within a local do-end block has the garbage collector kick in at an  
earlier moment.
I tried to fixate the module by putting the table returned by the  
pcall to require in either LUA_ENVIRONINDEX or LUA_GLOBALSINDEX but  
neither does work.
Clearly I am missing an essential point. But what?
I hope someone can point me in the right direction.