Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rules about Lua state shutdown and garbage collection metamethods

Tags:

lua

tl;dr version: is a garbage collection metamethod safe during a Lua state shutdown if it accesses global variables? What about local up-values?


When a lua_State is closed with lua_close, the Lua documentation says that all of the objects are deleted. And it says that any associated garbage-collection metamethods are guaranteed to be called.

Great.

However, there are two possible use cases of GC metamethods that are uncertain under this paradigm:

  1. What if you have a GC metamethod that uses a local variable that stores a collectable value. Say, a string, a function, etc. That is, your GC metamethod is defined as this:

    local some_string = "string"
    function mt:__gc() --[[Do something with some_string]] end
    

    What happens in this case? Is it possible for some_string to be collected? I know that if the object the metatable is on is being collected under normal circumstances, then this isn't possible. Lua would guarantee that the value of some_string would remain until the GC function itself is collected.

    But since all objects are being destroyed by lua_close, is it possible that upvalues of the GC function could be destroyed before the function is? I don't think it is (as this could cause all kinds of problems), but I'm looking for the real answer, not what I think.

  2. I admit that it is unlikely that #1 will be a problem, as it would create many issues with GC metamethods. However, this is a completely different matter:

    local some_string = "string"
    function mt:__gc() print(some_string) end
    

    This looks like #1, but it isn't. Why? Because it accesses a global variable. Namely, print.

    There is no direct association between the function and whatever value is stored in print (unlike case 1, where some_string is clearly an upvalue of the function). As such, it is possible for print to be collected before calling the function during Lua state shutdown.

The question is this: is it safe for a garbage collection metamethod to ever use anything from the global table (ignoring the possibility of deliberate sabotage of the global table vis-a-vis print = nil) during Lua state shutdown? Or, as a general rule, should they always explicitly make any functions or data they touch local? Will that be sufficient to avoid problems?

like image 695
Nicol Bolas Avatar asked Oct 06 '22 23:10

Nicol Bolas


1 Answers

Any data that is accessible from the __gc method is safe to access; this includes both locals and the tables that are accessible, like _G, which contains print.

What can be a problem are (un-)loaded C libraries; this affects Lua 5.1, and is fixed in Lua 5.2.1. See the patch for "Finalizers may call functions from a dynamic library after the library has been unloaded".

like image 82
Doug Currie Avatar answered Oct 10 '22 02:10

Doug Currie