lua-users home
lua-l archive

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

On Fri, Sep 16, 2011 at 4:40 PM, Mark Hamburg <> wrote:
On Sep 16, 2011, at 5:50 AM, Gaspard Bucher wrote:

After some more investigation, I think this is some edge case bug because I do not see what is wrong with the following pattern:

I found that the bug happens when the userdata has it's own environment and when this environment contains a lua_thread which in turn contains foobar:

   +-------- stack -------------------+
   | |
   v |
foobar ---> udata ---> fenv ---> udata_thread
              ^ |
              | |

The bug only appears when 'foobar' is in udata_thread's stack.

See the recent weak tables and finalization discussion, but I think this is another case of:

thread becomes unreachable
... so udata becomes unreachable
... so udata is queued for finalization
... so fenv and everything it leads to is marked in case it's needed for finalization
... so udata_thread gets marked
... so the code to clear weak tables keeps the thread around in your weak table (not shown) for another cycle

Then eventually, we finalize udata and bingo we have a path to a finalized userdatum.

The other discussion was moving toward a suggestion that the logic for clearing weak tables needed to be moved in the GC process.


Thanks to Mark and Gregory for your explanations and help here.

I followed Gregory's advice to cleanup the weak table by hand. To do this, I created a simple userdata whose sole purpose is to call a function on destruction:

---- wrap.t === weak table
thread.finalizer = lk.Finalizer(function()
  wrap.t.t = nil

Now the scheduler sees wrap.t.t as being nil (invalid) and does not try to run the coroutine (which is totally unreachable by now anyway).

I was scared of running Lua code during garbage collection but this solution works fine.

Thanks guys !