diff options
| author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2020-10-06 13:37:41 -0300 |
|---|---|---|
| committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2020-10-12 12:29:09 -0300 |
| commit | 9ecd446141f572252a57cb33d2bba6aa00d96a55 (patch) | |
| tree | cecd4f91efc181f652d6647e18772732262422a5 /testes | |
| parent | fb172d0a929432856983a51d4139f705d4c01365 (diff) | |
| download | lua-9ecd446141f572252a57cb33d2bba6aa00d96a55.tar.gz lua-9ecd446141f572252a57cb33d2bba6aa00d96a55.tar.bz2 lua-9ecd446141f572252a57cb33d2bba6aa00d96a55.zip | |
Avoid shrinking stacks to often
Shrink a stack only when the final stack size can be at most 2/3 the
previous size with half of its entries empty. This commit also
improves the clarity of 'luaD_growstack'.
Diffstat (limited to 'testes')
| -rw-r--r-- | testes/cstack.lua | 50 |
1 files changed, 49 insertions, 1 deletions
diff --git a/testes/cstack.lua b/testes/cstack.lua index 5767adf6..8ac48e89 100644 --- a/testes/cstack.lua +++ b/testes/cstack.lua | |||
| @@ -2,7 +2,7 @@ | |||
| 2 | -- See Copyright Notice in file all.lua | 2 | -- See Copyright Notice in file all.lua |
| 3 | 3 | ||
| 4 | 4 | ||
| 5 | print"testing C-stack overflow detection" | 5 | print"testing stack overflow detection" |
| 6 | 6 | ||
| 7 | -- Segmentation faults in these tests probably result from a C-stack | 7 | -- Segmentation faults in these tests probably result from a C-stack |
| 8 | -- overflow. To avoid these errors, you should set a smaller limit for | 8 | -- overflow. To avoid these errors, you should set a smaller limit for |
| @@ -98,4 +98,52 @@ do | |||
| 98 | print("final count: ", count) | 98 | print("final count: ", count) |
| 99 | end | 99 | end |
| 100 | 100 | ||
| 101 | |||
| 102 | if T then | ||
| 103 | print("testing stack recovery") | ||
| 104 | local N = 0 -- trace number of calls | ||
| 105 | local LIM = -1 -- will store N just before stack overflow | ||
| 106 | |||
| 107 | -- trace stack size; after stack overflow, it should be | ||
| 108 | -- the maximum allowed stack size. | ||
| 109 | local stack1 | ||
| 110 | local dummy | ||
| 111 | |||
| 112 | local function err(msg) | ||
| 113 | assert(string.find(msg, "stack overflow")) | ||
| 114 | local _, stacknow = T.stacklevel() | ||
| 115 | assert(stacknow == stack1 + 200) | ||
| 116 | end | ||
| 117 | |||
| 118 | -- When LIM==-1, the 'if' is not executed, so this function only | ||
| 119 | -- counts and stores the stack limits up to overflow. Then, LIM | ||
| 120 | -- becomes N, and then the 'if' code is run when the stack is | ||
| 121 | -- full. Then, there is a stack overflow inside 'xpcall', after which | ||
| 122 | -- the stack must have been restored back to its maximum normal size. | ||
| 123 | local function f() | ||
| 124 | dummy, stack1 = T.stacklevel() | ||
| 125 | if N == LIM then | ||
| 126 | xpcall(f, err) | ||
| 127 | local _, stacknow = T.stacklevel() | ||
| 128 | assert(stacknow == stack1) | ||
| 129 | return | ||
| 130 | end | ||
| 131 | N = N + 1 | ||
| 132 | f() | ||
| 133 | end | ||
| 134 | |||
| 135 | local topB, sizeB -- top and size Before overflow | ||
| 136 | local topA, sizeA -- top and size After overflow | ||
| 137 | topB, sizeB = T.stacklevel() | ||
| 138 | xpcall(f, err) | ||
| 139 | topA, sizeA = T.stacklevel() | ||
| 140 | -- sizes should be comparable | ||
| 141 | assert(topA == topB and sizeA < sizeB * 2) | ||
| 142 | print(string.format("maximum stack size: %d", stack1)) | ||
| 143 | LIM = N -- will stop recursion at maximum level | ||
| 144 | N = 0 -- to count again | ||
| 145 | f() | ||
| 146 | print"+" | ||
| 147 | end | ||
| 148 | |||
| 101 | print'OK' | 149 | print'OK' |
