diff --git a/testes/all.lua b/testes/all.lua index a4feeec1..a8e44024 100644 --- a/testes/all.lua +++ b/testes/all.lua @@ -154,18 +154,8 @@ end dofile('main.lua') -do - local next, setmetatable, stderr = next, setmetatable, io.stderr - -- track collections - local mt = {} - -- each time a table is collected, remark it for finalization - -- on next cycle - mt.__gc = function (o) - stderr:write'.' -- mark progress - local n = setmetatable(o, mt) -- remark it - end - local n = setmetatable({}, mt) -- create object -end +-- trace GC cycles +require"tracegc".start() report"gc.lua" local f = assert(loadfile('gc.lua')) diff --git a/testes/cstack.lua b/testes/cstack.lua index 7bd55063..213d15d4 100644 --- a/testes/cstack.lua +++ b/testes/cstack.lua @@ -2,6 +2,8 @@ -- See Copyright Notice in file all.lua +local tracegc = require"tracegc" + print"testing stack overflow detection" -- Segmentation faults in these tests probably result from a C-stack @@ -21,7 +23,9 @@ do print("testing stack overflow in message handling") count = count + 1 return 1 + loop(x, y, z) end + tracegc.stop() -- __gc should not be called with a full stack local res, msg = xpcall(loop, loop) + tracegc.start() assert(msg == "error in error handling") print("final count: ", count) end @@ -135,18 +139,18 @@ if T then local topB, sizeB -- top and size Before overflow local topA, sizeA -- top and size After overflow topB, sizeB = T.stacklevel() - collectgarbage("stop") -- __gc should not be called with a full stack + tracegc.stop() -- __gc should not be called with a full stack xpcall(f, err) - collectgarbage("restart") + tracegc.start() topA, sizeA = T.stacklevel() -- sizes should be comparable assert(topA == topB and sizeA < sizeB * 2) print(string.format("maximum stack size: %d", stack1)) LIM = N -- will stop recursion at maximum level N = 0 -- to count again - collectgarbage("stop") -- __gc should not be called with a full stack + tracegc.stop() -- __gc should not be called with a full stack f() - collectgarbage("restart") + tracegc.start() print"+" end diff --git a/testes/locals.lua b/testes/locals.lua index a93839db..2c67edbd 100644 --- a/testes/locals.lua +++ b/testes/locals.lua @@ -5,6 +5,8 @@ print('testing local variables and environments') local debug = require"debug" +local tracegc = require"tracegc" + -- bug in 5.1: @@ -554,9 +556,9 @@ do -- test for tbc variable high in the stack obj[1] = 100 flag = obj end) - collectgarbage("stop") + tracegc.stop() st, obj = xpcall(overflow, errorh, 0) - collectgarbage("restart") + tracegc.start() end) co() assert(not st and obj[1] == 10 and flag[1] == 100) diff --git a/testes/tracegc.lua b/testes/tracegc.lua new file mode 100644 index 00000000..9c5c1b3f --- /dev/null +++ b/testes/tracegc.lua @@ -0,0 +1,40 @@ +-- track collections + +local M = {} + +-- import list +local setmetatable, stderr, collectgarbage = + setmetatable, io.stderr, collectgarbage + +_ENV = nil + +local active = false + + +-- each time a table is collected, remark it for finalization on next +-- cycle +local mt = {} +function mt.__gc (o) + stderr:write'.' -- mark progress + if active then + setmetatable(o, mt) -- remark object for finalization + end +end + + +function M.start () + if not active then + active = true + setmetatable({}, mt) -- create initial object + end +end + + +function M.stop () + if active then + active = false + collectgarbage() -- call finalizer for the last time + end +end + +return M