lua-users home
lua-l archive

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

Hello jason,

Friday, August 25, 2006, 6:03:32 PM, you wrote:

jz> Thanks all of you.
jz> I suspend this problem for about one week and look at it again today.
jz> I compared the DLL case and exe case. The same C code works well
jz> in a exe but cause a heap error in dll. Below is what I get during debuging:

jz> When create a array in a DLL, it will allocate some memory and they are
jz> stored in the stack of the interpreter. When the script finished, the interpreter
jz> will call lua_close(L) to release the resources. But I found that, it unload the
jz> dll before clear the stack, so, the memory allocated in the DLL is invalid.

jz> For Lua 5.1

jz> lstate.c, line 210, in the function LUA_API void lua_close (lua_State *L)
jz> do {  /* repeat until no more errors */
jz>     L->ci = L->base_ci;
jz>     L->base = L->top = L->ci->base;
jz>     L->nCcalls = 0;
jz>   } while (luaD_rawrunprotected(L, callallgcTM, NULL) != 0); // Line 210
jz> Inside the luaD_rawrunprotected function, it will call
jz> luaC_callGCTM() function to clear all the user data,
jz> Finally, the routine go to the static int gctm (lua_State *L) function in loadlib.c, which
jz> unload the dll from the interpreter. So , all the memory allocated in DLL is invalid.

jz> Is my analysis correct?

jz> What I can't understand is, why only the array cause the
jz> problem, while normal table works.
jz> And I also don't understand why it works if I insert an element with index zero.

jz> Please help me.

jz> Thank you so much.

I guess you linked luacore twice. The lua interpreter static link
luacore lib once, and your dll link it again.

In ltable.c , line 73 :

#define dummynode               (&dummynode_)

static const Node dummynode_ = {
  {{NULL}, LUA_TNIL},  /* value */
  {{{NULL}, LUA_TNIL, NULL}}  /* key */

The dummynode is the static stuct .

When you create a table, it may call
  if (size == 0) {  /* no elements to hash part? */
    t->node = cast(Node *, dummynode);  /* use common `dummynode' */
    lsize = 0;

And when the table release, it checks t->node
void luaH_free (lua_State *L, Table *t) {
  if (t->node != dummynode)
    luaM_freearray(L, t->node, sizenode(t), Node);
  luaM_freearray(L, t->array, t->sizearray, TValue);
  luaM_free(L, t);

If you linked luacore twice, there are 2 copy of dummynode existed. It
may cause your problem.

ps. Lua table will put the index zero to hash part not array part.

Best regards,