diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2021-03-01 13:54:29 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2021-03-01 13:54:29 -0300 |
commit | 5276973224066e591b0f1a79c3b091d395848ac4 (patch) | |
tree | e72f167dca7796b4014b1833cb1e9eaed58a623e | |
parent | f9d857a81b87b695c1e3b34f1e7fe55884d1288f (diff) | |
download | lua-5276973224066e591b0f1a79c3b091d395848ac4.tar.gz lua-5276973224066e591b0f1a79c3b091d395848ac4.tar.bz2 lua-5276973224066e591b0f1a79c3b091d395848ac4.zip |
New test module 'tracegc'
New module easies the inclusion of GC tracing in individual test files.
-rw-r--r-- | testes/all.lua | 14 | ||||
-rw-r--r-- | testes/cstack.lua | 12 | ||||
-rw-r--r-- | testes/locals.lua | 6 | ||||
-rw-r--r-- | testes/tracegc.lua | 40 |
4 files changed, 54 insertions, 18 deletions
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 | |||
154 | 154 | ||
155 | dofile('main.lua') | 155 | dofile('main.lua') |
156 | 156 | ||
157 | do | 157 | -- trace GC cycles |
158 | local next, setmetatable, stderr = next, setmetatable, io.stderr | 158 | require"tracegc".start() |
159 | -- track collections | ||
160 | local mt = {} | ||
161 | -- each time a table is collected, remark it for finalization | ||
162 | -- on next cycle | ||
163 | mt.__gc = function (o) | ||
164 | stderr:write'.' -- mark progress | ||
165 | local n = setmetatable(o, mt) -- remark it | ||
166 | end | ||
167 | local n = setmetatable({}, mt) -- create object | ||
168 | end | ||
169 | 159 | ||
170 | report"gc.lua" | 160 | report"gc.lua" |
171 | local f = assert(loadfile('gc.lua')) | 161 | 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 @@ | |||
2 | -- See Copyright Notice in file all.lua | 2 | -- See Copyright Notice in file all.lua |
3 | 3 | ||
4 | 4 | ||
5 | local tracegc = require"tracegc" | ||
6 | |||
5 | print"testing stack overflow detection" | 7 | print"testing stack overflow detection" |
6 | 8 | ||
7 | -- Segmentation faults in these tests probably result from a C-stack | 9 | -- Segmentation faults in these tests probably result from a C-stack |
@@ -21,7 +23,9 @@ do print("testing stack overflow in message handling") | |||
21 | count = count + 1 | 23 | count = count + 1 |
22 | return 1 + loop(x, y, z) | 24 | return 1 + loop(x, y, z) |
23 | end | 25 | end |
26 | tracegc.stop() -- __gc should not be called with a full stack | ||
24 | local res, msg = xpcall(loop, loop) | 27 | local res, msg = xpcall(loop, loop) |
28 | tracegc.start() | ||
25 | assert(msg == "error in error handling") | 29 | assert(msg == "error in error handling") |
26 | print("final count: ", count) | 30 | print("final count: ", count) |
27 | end | 31 | end |
@@ -135,18 +139,18 @@ if T then | |||
135 | local topB, sizeB -- top and size Before overflow | 139 | local topB, sizeB -- top and size Before overflow |
136 | local topA, sizeA -- top and size After overflow | 140 | local topA, sizeA -- top and size After overflow |
137 | topB, sizeB = T.stacklevel() | 141 | topB, sizeB = T.stacklevel() |
138 | collectgarbage("stop") -- __gc should not be called with a full stack | 142 | tracegc.stop() -- __gc should not be called with a full stack |
139 | xpcall(f, err) | 143 | xpcall(f, err) |
140 | collectgarbage("restart") | 144 | tracegc.start() |
141 | topA, sizeA = T.stacklevel() | 145 | topA, sizeA = T.stacklevel() |
142 | -- sizes should be comparable | 146 | -- sizes should be comparable |
143 | assert(topA == topB and sizeA < sizeB * 2) | 147 | assert(topA == topB and sizeA < sizeB * 2) |
144 | print(string.format("maximum stack size: %d", stack1)) | 148 | print(string.format("maximum stack size: %d", stack1)) |
145 | LIM = N -- will stop recursion at maximum level | 149 | LIM = N -- will stop recursion at maximum level |
146 | N = 0 -- to count again | 150 | N = 0 -- to count again |
147 | collectgarbage("stop") -- __gc should not be called with a full stack | 151 | tracegc.stop() -- __gc should not be called with a full stack |
148 | f() | 152 | f() |
149 | collectgarbage("restart") | 153 | tracegc.start() |
150 | print"+" | 154 | print"+" |
151 | end | 155 | end |
152 | 156 | ||
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') | |||
5 | 5 | ||
6 | local debug = require"debug" | 6 | local debug = require"debug" |
7 | 7 | ||
8 | local tracegc = require"tracegc" | ||
9 | |||
8 | 10 | ||
9 | -- bug in 5.1: | 11 | -- bug in 5.1: |
10 | 12 | ||
@@ -554,9 +556,9 @@ do -- test for tbc variable high in the stack | |||
554 | obj[1] = 100 | 556 | obj[1] = 100 |
555 | flag = obj | 557 | flag = obj |
556 | end) | 558 | end) |
557 | collectgarbage("stop") | 559 | tracegc.stop() |
558 | st, obj = xpcall(overflow, errorh, 0) | 560 | st, obj = xpcall(overflow, errorh, 0) |
559 | collectgarbage("restart") | 561 | tracegc.start() |
560 | end) | 562 | end) |
561 | co() | 563 | co() |
562 | assert(not st and obj[1] == 10 and flag[1] == 100) | 564 | 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 @@ | |||
1 | -- track collections | ||
2 | |||
3 | local M = {} | ||
4 | |||
5 | -- import list | ||
6 | local setmetatable, stderr, collectgarbage = | ||
7 | setmetatable, io.stderr, collectgarbage | ||
8 | |||
9 | _ENV = nil | ||
10 | |||
11 | local active = false | ||
12 | |||
13 | |||
14 | -- each time a table is collected, remark it for finalization on next | ||
15 | -- cycle | ||
16 | local mt = {} | ||
17 | function mt.__gc (o) | ||
18 | stderr:write'.' -- mark progress | ||
19 | if active then | ||
20 | setmetatable(o, mt) -- remark object for finalization | ||
21 | end | ||
22 | end | ||
23 | |||
24 | |||
25 | function M.start () | ||
26 | if not active then | ||
27 | active = true | ||
28 | setmetatable({}, mt) -- create initial object | ||
29 | end | ||
30 | end | ||
31 | |||
32 | |||
33 | function M.stop () | ||
34 | if active then | ||
35 | active = false | ||
36 | collectgarbage() -- call finalizer for the last time | ||
37 | end | ||
38 | end | ||
39 | |||
40 | return M | ||