lua-users home
lua-l archive

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


in Lua 5.1.4 (patch-lua-5.1.4-3) through lua-5.2.0-work5, if a module
fails to load and we later reattempt to load the module, we get an odd
error due to inconsistent sentinel state (another need for resource
cleanup on scope exit maybe):

  $ echo 'if not ok then error"fail" end' > foo.lua
  $ lua -e 'pcall(require, "foo"); ok=true; require "foo"'
  lua: (command line):1: loop or previous error loading module 'foo'
  stack traceback:
  	[C]: in function 'require'
  	(command line):1: in main chunk
  	[C]: ?

In Lua-5.2.0-alpha, it runs without error.  This problem was noticed
in debugging a problem in the vstruct test suite [1].  I suspect this
problem was also reported and corrected here [2].  There's a number of
changes in loadlib.c between lua-5.2.0-work5 and lua-5.2.0-alpha, but
I think the only important one here is

@@ -469,14 +461,12 @@ static int ll_require (lua_State *L) {
     else
       lua_pop(L, 1);
   }
-  lua_pushlightuserdata(L, sentinel);
-  lua_setfield(L, 2, name);  /* _LOADED[name] = sentinel */
   lua_pushstring(L, name);  /* pass name as argument to module */
   lua_call(L, 1, 1);  /* run loaded module */
   if (!lua_isnil(L, -1))  /* non-nil return? */
     lua_setfield(L, 2, name);  /* _LOADED[name] = returned value */

So, it is no longer setting any sentinel.  Examining this further,
observe Lua 5.1.4:

  $echo 'require "loop"' > loop.lua
  $ lua loop.lua
  lua: ./loop.lua:1: loop or previous error loading module 'loop'
  stack traceback:
  	[C]: in function 'require'
  	./loop.lua:1: in main chunk
  	[C]: in function 'require'
  	loop.lua:1: in main chunk
  	[C]: ?

compared to Lua 5.2.0-alpha:

  $ lua loop.lua
  ./src/lua: C stack overflow
  stack traceback:
  	[C]: in function 'require'
  	./loop.lua:1: in main chunk
  	[C]: in function 'require'
  	./loop.lua:1: in main chunk
  	[C]: in function 'require'
  	./loop.lua:1: in main chunk
  	[C]: in function 'require'
  	./loop.lua:1: in main chunk
  	[C]: in function 'require'
  	./loop.lua:1: in main chunk
  	...
  	[C]: in function 'require'
  	./loop.lua:1: in main chunk
  	[C]: in function 'require'
  	./loop.lua:1: in main chunk
  	[C]: in function 'require'
  	./loop.lua:1: in main chunk
  	[C]: in function 'require'
  	./loop.lua:1: in main chunk
  	[C]: in function 'require'
  	loop.lua:1: in main chunk
  	[C]: in ?

So, Lua 5.2.0-alpha eliminates the sentinel and just relies on Lua
stack overflow.  That change may be fine, but the bug still exists in
5.1.  (The only breakage from this change that comes to mind is that
there has been known to exist an ugly hack, possibly based on
undefined behavior, of checking for a sentinel in determining whether
a source file is loaded via the command-line or via require [3].)

(Side-note: I found [4] of some use to the above bisection of the
source, lacking [5].)

[1] https://github.com/ToxicFrog/vstruct/issues#issue/10
[2] http://lua-users.org/lists/lua-l/2010-11/msg00152.html
[3] http://lua-users.org/lists/lua-l/2007-02/msg00128.html
[4] https://github.com/ittner/Lua-experimentation
[5] http://www.lua.org/faq.html#1.8