Software / code / prosody
Comparison
spec/util_debug_spec.lua @ 11177:37dc2a6144d1 0.11
util.debug: Fix locals being reported under wrong stack frame in some cases (+tests!!)
| author | Matthew Wild <mwild1@gmail.com> |
|---|---|
| date | Fri, 16 Oct 2020 13:38:04 +0100 |
comparison
equal
deleted
inserted
replaced
| 11175:235537247aa3 | 11177:37dc2a6144d1 |
|---|---|
| 1 local dbg = require "util.debug"; | |
| 2 | |
| 3 describe("util.debug", function () | |
| 4 describe("traceback()", function () | |
| 5 it("works", function () | |
| 6 local tb = dbg.traceback(); | |
| 7 assert.is_string(tb); | |
| 8 end); | |
| 9 end); | |
| 10 describe("get_traceback_table()", function () | |
| 11 it("works", function () | |
| 12 local count = 0; | |
| 13 -- MUST stay in sync with the line numbers of these functions: | |
| 14 local f1_defined, f3_defined = 43, 15; | |
| 15 local function f3(f3_param) --luacheck: ignore 212/f3_param | |
| 16 count = count + 1; | |
| 17 | |
| 18 for i = 1, 2 do | |
| 19 local tb = dbg.get_traceback_table(i == 1 and coroutine.running() or nil, 0); | |
| 20 assert.is_table(tb); | |
| 21 --print(dbg.traceback(), "\n\n\n", require "util.serialization".serialize(tb, { fatal = false, unquoted = true})); | |
| 22 local found_f1, found_f3; | |
| 23 for _, frame in ipairs(tb) do | |
| 24 if frame.info.linedefined == f1_defined then | |
| 25 assert.equal(0, #frame.locals); | |
| 26 assert.equal("f2", frame.upvalues[1].name); | |
| 27 assert.equal("f1_upvalue", frame.upvalues[2].name); | |
| 28 found_f1 = true; | |
| 29 elseif frame.info.linedefined == f3_defined then | |
| 30 assert.equal("f3_param", frame.locals[1].name); | |
| 31 found_f3 = true; | |
| 32 end | |
| 33 end | |
| 34 assert.is_true(found_f1); | |
| 35 assert.is_true(found_f3); | |
| 36 end | |
| 37 end | |
| 38 local function f2() | |
| 39 local f2_local = "hello"; | |
| 40 return f3(f2_local); | |
| 41 end | |
| 42 local f1_upvalue = "upvalue1"; | |
| 43 local function f1() | |
| 44 f2(f1_upvalue); | |
| 45 end | |
| 46 | |
| 47 -- ok/err are caught and re-thrown so that | |
| 48 -- busted gets to handle them in its own way | |
| 49 local ok, err; | |
| 50 local function hook() | |
| 51 debug.sethook(); | |
| 52 ok, err = pcall(f1); | |
| 53 end | |
| 54 | |
| 55 -- Test the traceback is correct in various | |
| 56 -- types of caller environments | |
| 57 | |
| 58 -- From a Lua hook | |
| 59 debug.sethook(hook, "crl", 1); | |
| 60 local a = string.sub("abcdef", 3, 4); | |
| 61 assert.equal("cd", a); | |
| 62 debug.sethook(); | |
| 63 assert.equal(1, count); | |
| 64 | |
| 65 if not ok then | |
| 66 error(err); | |
| 67 end | |
| 68 ok, err = nil, nil; | |
| 69 | |
| 70 -- From a signal handler (C hook) | |
| 71 require "util.signal".signal("SIGUSR1", hook); | |
| 72 require "util.signal".raise("SIGUSR1"); | |
| 73 assert.equal(2, count); | |
| 74 | |
| 75 if not ok then | |
| 76 error(err); | |
| 77 end | |
| 78 ok, err = nil, nil; | |
| 79 | |
| 80 -- Inside a coroutine | |
| 81 local co = coroutine.create(function () | |
| 82 hook(); | |
| 83 end); | |
| 84 coroutine.resume(co); | |
| 85 | |
| 86 if not ok then | |
| 87 error(err); | |
| 88 end | |
| 89 | |
| 90 assert.equal(3, count); | |
| 91 end); | |
| 92 end); | |
| 93 end); |