summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2012-04-12 13:25:25 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2012-04-12 13:25:25 -0300
commit1485ea2ee742779b0030152ebde92a8370518afa (patch)
tree28c819860d2d844626a1d6cdf324ca21f5147f8c
parentb10dbe5c727eedace5c84addd0573bfa1b0c027a (diff)
downloadlua-1485ea2ee742779b0030152ebde92a8370518afa.tar.gz
lua-1485ea2ee742779b0030152ebde92a8370518afa.tar.bz2
lua-1485ea2ee742779b0030152ebde92a8370518afa.zip
Finalizers may call functions from a dynamic library after
the library has been unloaded
-rw-r--r--bugs104
1 files changed, 102 insertions, 2 deletions
diff --git a/bugs b/bugs
index 8708dd92..ff499e50 100644
--- a/bugs
+++ b/bugs
@@ -1880,8 +1880,8 @@ patch = [[
1880+++ lundump.c 2008/04/04 19:51:41 2.7.1.4 1880+++ lundump.c 2008/04/04 19:51:41 2.7.1.4
1881@@ -1,5 +1,5 @@ 1881@@ -1,5 +1,5 @@
1882 /* 1882 /*
1883-** $Id: bugs,v 1.111 2011/10/21 19:34:23 roberto Exp roberto $ 1883-** $Id: bugs,v 1.112 2012/01/20 18:32:13 roberto Exp roberto $
1884+** $Id: bugs,v 1.111 2011/10/21 19:34:23 roberto Exp roberto $ 1884+** $Id: bugs,v 1.112 2012/01/20 18:32:13 roberto Exp roberto $
1885 ** load precompiled Lua chunks 1885 ** load precompiled Lua chunks
1886 ** See Copyright Notice in lua.h 1886 ** See Copyright Notice in lua.h
1887 */ 1887 */
@@ -2520,6 +2520,106 @@ patch = [[
2520]] 2520]]
2521} 2521}
2522 2522
2523Bug{
2524what = [[Finalizers may call functions from a dynamic library after
2525the library has been unloaded]],
2526report = [[Josh Haberman, 2012/04/08]],
2527since = [[5.1]],
2528example = [[
2529local u = setmetatable({}, {__gc = function () foo() end})
2530local m = require 'mod' -- 'mod' may be any dynamic library written in C
2531foo = m.foo -- 'foo' may be any function from 'mod'
2532-- end program; it crashes
2533]],
2534patch = [[
2535===================================================================
2536RCS file: RCS/loadlib.c,v
2537retrieving revision 1.108
2538diff -r1.108 loadlib.c
253995c95
2540< #define LIBPREFIX "LOADLIB: "
2541---
2542> #define CLIBS "_CLIBS"
2543251,266c251,256
2544<
2545< static void **ll_register (lua_State *L, const char *path) {
2546< void **plib;
2547< lua_pushfstring(L, "%s%s", LIBPREFIX, path);
2548< lua_gettable(L, LUA_REGISTRYINDEX); /* check library in registry? */
2549< if (!lua_isnil(L, -1)) /* is there an entry? */
2550< plib = (void **)lua_touserdata(L, -1);
2551< else { /* no entry yet; create one */
2552< lua_pop(L, 1); /* remove result from gettable */
2553< plib = (void **)lua_newuserdata(L, sizeof(const void *));
2554< *plib = NULL;
2555< luaL_setmetatable(L, "_LOADLIB");
2556< lua_pushfstring(L, "%s%s", LIBPREFIX, path);
2557< lua_pushvalue(L, -2);
2558< lua_settable(L, LUA_REGISTRYINDEX);
2559< }
2560---
2561> static void *ll_checkclib (lua_State *L, const char *path) {
2562> void *plib;
2563> lua_getfield(L, LUA_REGISTRYINDEX, CLIBS);
2564> lua_getfield(L, -1, path);
2565> plib = lua_touserdata(L, -1); /* plib = CLIBS[path] */
2566> lua_pop(L, 2); /* pop CLIBS table and 'plib' */
2567270a261,270
2568> static void ll_addtoclib (lua_State *L, const char *path, void *plib) {
2569> lua_getfield(L, LUA_REGISTRYINDEX, CLIBS);
2570> lua_pushlightuserdata(L, plib);
2571> lua_pushvalue(L, -1);
2572> lua_setfield(L, -3, path); /* CLIBS[path] = plib */
2573> lua_rawseti(L, -2, luaL_len(L, -2) + 1); /* CLIBS[#CLIBS + 1] = plib */
2574> lua_pop(L, 1); /* pop CLIBS table */
2575> }
2576>
2577>
2578272,273c272,273
2579< ** __gc tag method: calls library's `ll_unloadlib' function with the lib
2580< ** handle
2581---
2582> ** __gc tag method for CLIBS table: calls 'll_unloadlib' for all lib
2583> ** handles in list CLIBS
2584276,278c276,281
2585< void **lib = (void **)luaL_checkudata(L, 1, "_LOADLIB");
2586< if (*lib) ll_unloadlib(*lib);
2587< *lib = NULL; /* mark library as closed */
2588---
2589> int n = luaL_len(L, 1);
2590> for (; n >= 1; n--) { /* for each handle, in reverse order */
2591> lua_rawgeti(L, 1, n); /* get handle CLIBS[n] */
2592> ll_unloadlib(lua_touserdata(L, -1));
2593> lua_pop(L, 1); /* pop handle */
2594> }
2595284,286c287,292
2596< void **reg = ll_register(L, path);
2597< if (*reg == NULL) *reg = ll_load(L, path, *sym == '*');
2598< if (*reg == NULL) return ERRLIB; /* unable to load library */
2599---
2600> void *reg = ll_checkclib(L, path); /* check loaded C libraries */
2601> if (reg == NULL) { /* must load library? */
2602> reg = ll_load(L, path, *sym == '*');
2603> if (reg == NULL) return ERRLIB; /* unable to load library */
2604> ll_addtoclib(L, path, reg);
2605> }
2606292c298
2607< lua_CFunction f = ll_sym(L, *reg, sym);
2608---
2609> lua_CFunction f = ll_sym(L, reg, sym);
2610675,676c681,683
2611< /* create new type _LOADLIB */
2612< luaL_newmetatable(L, "_LOADLIB");
2613---
2614> /* create table CLIBS to keep track of loaded C libraries */
2615> luaL_getsubtable(L, LUA_REGISTRYINDEX, CLIBS);
2616> lua_createtable(L, 0, 1); /* metatable for CLIBS */
2617678a686
2618> lua_setmetatable(L, -2);
2619]]
2620}
2621
2622
2523--[=[ 2623--[=[
2524Bug{ 2624Bug{
2525what = [[ ]], 2625what = [[ ]],