Skip to content

Instantly share code, notes, and snippets.

@lubyk
Created September 16, 2011 07:00
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save lubyk/1221403 to your computer and use it in GitHub Desktop.
Save lubyk/1221403 to your computer and use it in GitHub Desktop.
Lua garbage collection weirdness
~~~ = link from table with weak values
********************************************************************************
State before removing 'foobar':
+----------------------------------------+
| |
v |
scheduler ---> wrap ---> t ~~~> thread ---> coroutine --- (up-value) --> foobar ---> udata
^ ^
| |
main ----------------------------------------------------------------------+
********************************************************************************
[EDIT] Dependency graph in foobar (makes the bug appear)
+-------- stack -------------------+
| |
v |
foobar ---> udata ---> fenv ---> udata_thread
^ |
| |
+---------+
The bug only appears when 'foobar' is in udata_thread's stack.
********************************************************************************
********************************************************************************
Setting 'foobar' to nil
main.foobar = nil
collectgarbage()
+----------------------------------------+
| |
v |
scheduler ---> wrap ---> t ~~~> thread ---> coroutine --- (up-value) --> foobar ---> 0x0 udata
^
|
main
The coroutine exists and when the scheduler calls
coroutine.resume(wrap.t.thread.co) we SEGFAULT.
********************************************************************************
********************************************************************************
main.foobar.thread = nil
main.foobar = nil
collectgarbage()
scheduler ---> wrap ---> t
^
|
main
Coroutine removed with 'foobar': all OK
********************************************************************************
********************************************************************************
Complete dependency graph
main.foobar = nil
collectgarbage()
+----------------------------------------+
| |
v |
scheduler ---> wrap ---> t ~~~> thread ---> coroutine --- (up-value) --> foobar ---> 0x0 udata
^
|
main
The coroutine exists and when the scheduler calls
coroutine.resume(wrap.t.thread.co) we SEGFAULT.
********************************************************************************
********************************************************************************
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment