db.lua 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062
  1. -- $Id: testes/db.lua $
  2. -- See Copyright Notice in file lua.h
  3. -- testing debug library
  4. local debug = require "debug"
  5. local function dostring(s) return assert(load(s))() end
  6. print"testing debug library and debug information"
  7. do
  8. local a=1
  9. end
  10. assert(not debug.gethook())
  11. local testline = 19 -- line where 'test' is defined
  12. local function test (s, l, p) -- this must be line 19
  13. collectgarbage() -- avoid gc during trace
  14. local function f (event, line)
  15. assert(event == 'line')
  16. local l = table.remove(l, 1)
  17. if p then print(l, line) end
  18. assert(l == line, "wrong trace!!")
  19. end
  20. debug.sethook(f,"l"); load(s)(); debug.sethook()
  21. assert(#l == 0)
  22. end
  23. do
  24. assert(not pcall(debug.getinfo, print, "X")) -- invalid option
  25. assert(not pcall(debug.getinfo, 0, ">")) -- invalid option
  26. assert(not debug.getinfo(1000)) -- out of range level
  27. assert(not debug.getinfo(-1)) -- out of range level
  28. local a = debug.getinfo(print)
  29. assert(a.what == "C" and a.short_src == "[C]")
  30. a = debug.getinfo(print, "L")
  31. assert(a.activelines == nil)
  32. local b = debug.getinfo(test, "SfL")
  33. assert(b.name == nil and b.what == "Lua" and b.linedefined == testline and
  34. b.lastlinedefined == b.linedefined + 10 and
  35. b.func == test and not string.find(b.short_src, "%["))
  36. assert(b.activelines[b.linedefined + 1] and
  37. b.activelines[b.lastlinedefined])
  38. assert(not b.activelines[b.linedefined] and
  39. not b.activelines[b.lastlinedefined + 1])
  40. end
  41. -- bug in 5.4.4-5.4.6: activelines in vararg functions
  42. -- without debug information
  43. do
  44. local func = load(string.dump(load("print(10)"), true))
  45. local actl = debug.getinfo(func, "L").activelines
  46. assert(#actl == 0) -- no line info
  47. end
  48. -- test file and string names truncation
  49. local a = "function f () end"
  50. local function dostring (s, x) return load(s, x)() end
  51. dostring(a)
  52. assert(debug.getinfo(f).short_src == string.format('[string "%s"]', a))
  53. dostring(a..string.format("; %s\n=1", string.rep('p', 400)))
  54. assert(string.find(debug.getinfo(f).short_src, '^%[string [^\n]*%.%.%."%]$'))
  55. dostring(a..string.format("; %s=1", string.rep('p', 400)))
  56. assert(string.find(debug.getinfo(f).short_src, '^%[string [^\n]*%.%.%."%]$'))
  57. dostring("\n"..a)
  58. assert(debug.getinfo(f).short_src == '[string "..."]')
  59. dostring(a, "")
  60. assert(debug.getinfo(f).short_src == '[string ""]')
  61. dostring(a, "@xuxu")
  62. assert(debug.getinfo(f).short_src == "xuxu")
  63. dostring(a, "@"..string.rep('p', 1000)..'t')
  64. assert(string.find(debug.getinfo(f).short_src, "^%.%.%.p*t$"))
  65. dostring(a, "=xuxu")
  66. assert(debug.getinfo(f).short_src == "xuxu")
  67. dostring(a, string.format("=%s", string.rep('x', 500)))
  68. assert(string.find(debug.getinfo(f).short_src, "^x*$"))
  69. dostring(a, "=")
  70. assert(debug.getinfo(f).short_src == "")
  71. _G.a = nil; _G.f = nil;
  72. _G[string.rep("p", 400)] = nil
  73. repeat
  74. local g = {x = function ()
  75. local a = debug.getinfo(2)
  76. assert(a.name == 'f' and a.namewhat == 'local')
  77. a = debug.getinfo(1)
  78. assert(a.name == 'x' and a.namewhat == 'field')
  79. return 'xixi'
  80. end}
  81. local f = function () return 1+1 and (not 1 or g.x()) end
  82. assert(f() == 'xixi')
  83. g = debug.getinfo(f)
  84. assert(g.what == "Lua" and g.func == f and g.namewhat == "" and not g.name)
  85. function f (x, name) -- local!
  86. name = name or 'f'
  87. local a = debug.getinfo(1)
  88. assert(a.name == name and a.namewhat == 'local')
  89. return x
  90. end
  91. -- breaks in different conditions
  92. if 3>4 then break end; f()
  93. if 3<4 then a=1 else break end; f()
  94. while 1 do local x=10; break end; f()
  95. local b = 1
  96. if 3>4 then return math.sin(1) end; f()
  97. a = 3<4; f()
  98. a = 3<4 or 1; f()
  99. repeat local x=20; if 4>3 then f() else break end; f() until 1
  100. g = {}
  101. f(g).x = f(2) and f(10)+f(9)
  102. assert(g.x == f(19))
  103. function g(x) if not x then return 3 end return (x('a', 'x')) end
  104. assert(g(f) == 'a')
  105. until 1
  106. test([[if
  107. math.sin(1)
  108. then
  109. a=1
  110. else
  111. a=2
  112. end
  113. ]], {2,4,7})
  114. test([[
  115. local function foo()
  116. end
  117. foo()
  118. A = 1
  119. A = 2
  120. A = 3
  121. ]], {2, 3, 2, 4, 5, 6})
  122. _G.A = nil
  123. test([[--
  124. if nil then
  125. a=1
  126. else
  127. a=2
  128. end
  129. ]], {2,5,6})
  130. test([[a=1
  131. repeat
  132. a=a+1
  133. until a==3
  134. ]], {1,3,4,3,4})
  135. test([[ do
  136. return
  137. end
  138. ]], {2})
  139. test([[local a
  140. a=1
  141. while a<=3 do
  142. a=a+1
  143. end
  144. ]], {1,2,3,4,3,4,3,4,3,5})
  145. test([[while math.sin(1) do
  146. if math.sin(1)
  147. then break
  148. end
  149. end
  150. a=1]], {1,2,3,6})
  151. test([[for i=1,3 do
  152. a=i
  153. end
  154. ]], {1,2,1,2,1,2,1,3})
  155. test([[for i,v in pairs{'a','b'} do
  156. a=tostring(i) .. v
  157. end
  158. ]], {1,2,1,2,1,3})
  159. test([[for i=1,4 do a=1 end]], {1,1,1,1})
  160. _G.a = nil
  161. do -- testing line info/trace with large gaps in source
  162. local a = {1, 2, 3, 10, 124, 125, 126, 127, 128, 129, 130,
  163. 255, 256, 257, 500, 1000}
  164. local s = [[
  165. local b = {10}
  166. a = b[1] X + Y b[1]
  167. b = 4
  168. ]]
  169. for _, i in ipairs(a) do
  170. local subs = {X = string.rep("\n", i)}
  171. for _, j in ipairs(a) do
  172. subs.Y = string.rep("\n", j)
  173. local s = string.gsub(s, "[XY]", subs)
  174. test(s, {1, 2 + i, 2 + i + j, 2 + i, 2 + i + j, 3 + i + j})
  175. end
  176. end
  177. end
  178. _G.a = nil
  179. do -- testing active lines
  180. local function checkactivelines (f, lines)
  181. local t = debug.getinfo(f, "SL")
  182. for _, l in pairs(lines) do
  183. l = l + t.linedefined
  184. assert(t.activelines[l])
  185. t.activelines[l] = undef
  186. end
  187. assert(next(t.activelines) == nil) -- no extra lines
  188. end
  189. checkactivelines(function (...) -- vararg function
  190. -- 1st line is empty
  191. -- 2nd line is empty
  192. -- 3th line is empty
  193. local a = 20
  194. -- 5th line is empty
  195. local b = 30
  196. -- 7th line is empty
  197. end, {4, 6, 8})
  198. checkactivelines(function (a)
  199. -- 1st line is empty
  200. -- 2nd line is empty
  201. local a = 20
  202. local b = 30
  203. -- 5th line is empty
  204. end, {3, 4, 6})
  205. checkactivelines(function (a, b, ...) end, {0})
  206. checkactivelines(function (a, b)
  207. end, {1})
  208. for _, n in pairs{0, 1, 2, 10, 50, 100, 1000, 10000} do
  209. checkactivelines(
  210. load(string.format("%s return 1", string.rep("\n", n))),
  211. {n + 1})
  212. end
  213. end
  214. print'+'
  215. -- invalid levels in [gs]etlocal
  216. assert(not pcall(debug.getlocal, 20, 1))
  217. assert(not pcall(debug.setlocal, -1, 1, 10))
  218. -- parameter names
  219. local function foo (a,b,...) local d, e end
  220. local co = coroutine.create(foo)
  221. assert(debug.getlocal(foo, 1) == 'a')
  222. assert(debug.getlocal(foo, 2) == 'b')
  223. assert(not debug.getlocal(foo, 3))
  224. assert(debug.getlocal(co, foo, 1) == 'a')
  225. assert(debug.getlocal(co, foo, 2) == 'b')
  226. assert(not debug.getlocal(co, foo, 3))
  227. assert(not debug.getlocal(print, 1))
  228. local function foo () return (debug.getlocal(1, -1)) end
  229. assert(not foo(10))
  230. -- varargs
  231. local function foo (a, ...)
  232. local t = table.pack(...)
  233. for i = 1, t.n do
  234. local n, v = debug.getlocal(1, -i)
  235. assert(n == "(vararg)" and v == t[i])
  236. end
  237. assert(not debug.getlocal(1, -(t.n + 1)))
  238. assert(not debug.setlocal(1, -(t.n + 1), 30))
  239. if t.n > 0 then
  240. (function (x)
  241. assert(debug.setlocal(2, -1, x) == "(vararg)")
  242. assert(debug.setlocal(2, -t.n, x) == "(vararg)")
  243. end)(430)
  244. assert(... == 430)
  245. end
  246. end
  247. foo()
  248. foo(print)
  249. foo(200, 3, 4)
  250. local a = {}
  251. for i = 1, (_soft and 100 or 1000) do a[i] = i end
  252. foo(table.unpack(a))
  253. do -- test hook presence in debug info
  254. assert(not debug.gethook())
  255. local count = 0
  256. local function f ()
  257. assert(debug.getinfo(1).namewhat == "hook")
  258. local sndline = string.match(debug.traceback(), "\n(.-)\n")
  259. assert(string.find(sndline, "hook"))
  260. count = count + 1
  261. end
  262. debug.sethook(f, "l")
  263. local a = 0
  264. _ENV.a = a
  265. a = 1
  266. debug.sethook()
  267. assert(count == 4)
  268. end
  269. _ENV.a = nil
  270. -- hook table has weak keys
  271. assert(getmetatable(debug.getregistry()._HOOKKEY).__mode == 'k')
  272. a = {}; local L = nil
  273. local glob = 1
  274. local oldglob = glob
  275. debug.sethook(function (e,l)
  276. collectgarbage() -- force GC during a hook
  277. local f, m, c = debug.gethook()
  278. assert(m == 'crl' and c == 0)
  279. if e == "line" then
  280. if glob ~= oldglob then
  281. L = l-1 -- get the first line where "glob" has changed
  282. oldglob = glob
  283. end
  284. elseif e == "call" then
  285. local f = debug.getinfo(2, "f").func
  286. a[f] = 1
  287. else assert(e == "return")
  288. end
  289. end, "crl")
  290. function f(a,b)
  291. -- declare some globals to check that they don't interfere with 'getlocal'
  292. global collectgarbage
  293. collectgarbage()
  294. local _, x = debug.getlocal(1, 1)
  295. global assert, g, string
  296. local _, y = debug.getlocal(1, 2)
  297. assert(x == a and y == b)
  298. assert(debug.setlocal(2, 3, "pera") == "AA".."AA")
  299. assert(debug.setlocal(2, 4, "manga") == "B")
  300. x = debug.getinfo(2)
  301. assert(x.func == g and x.what == "Lua" and x.name == 'g' and
  302. x.nups == 2 and string.find(x.source, "^@.*db%.lua$"))
  303. glob = glob+1
  304. assert(debug.getinfo(1, "l").currentline == L+1)
  305. assert(debug.getinfo(1, "l").currentline == L+2)
  306. end
  307. function foo()
  308. glob = glob+1
  309. assert(debug.getinfo(1, "l").currentline == L+1)
  310. end; foo() -- set L
  311. -- check line counting inside strings and empty lines
  312. local _ = 'alo\
  313. alo' .. [[
  314. ]]
  315. --[[
  316. ]]
  317. assert(debug.getinfo(1, "l").currentline == L+11) -- check count of lines
  318. function g (...)
  319. local arg = {...}
  320. do local a,b,c; a=math.sin(40); end
  321. local feijao
  322. local AAAA,B = "xuxu", "abacate"
  323. f(AAAA,B)
  324. assert(AAAA == "pera" and B == "manga")
  325. do
  326. global *
  327. local B = 13
  328. global<const> assert
  329. local x,y = debug.getlocal(1,5)
  330. assert(x == 'B' and y == 13)
  331. end
  332. end
  333. g()
  334. assert(a[f] and a[g] and a[assert] and a[debug.getlocal] and not a[print])
  335. -- tests for manipulating non-registered locals (C and Lua temporaries)
  336. local n, v = debug.getlocal(0, 1)
  337. assert(v == 0 and n == "(C temporary)")
  338. local n, v = debug.getlocal(0, 2)
  339. assert(v == 2 and n == "(C temporary)")
  340. assert(not debug.getlocal(0, 3))
  341. assert(not debug.getlocal(0, 0))
  342. function f()
  343. assert(select(2, debug.getlocal(2,3)) == 1)
  344. assert(not debug.getlocal(2,4))
  345. debug.setlocal(2, 3, 10)
  346. return 20
  347. end
  348. function g(a,b) return (a+1) + f() end
  349. assert(g(0,0) == 30)
  350. _G.f, _G.g = nil
  351. debug.sethook(nil);
  352. assert(not debug.gethook())
  353. -- minimal tests for setuservalue/getuservalue
  354. do
  355. assert(not debug.setuservalue(io.stdin, 10))
  356. local a, b = debug.getuservalue(io.stdin, 10)
  357. assert(a == nil and not b)
  358. end
  359. -- testing interaction between multiple values x hooks
  360. do
  361. local function f(...) return 3, ... end
  362. local count = 0
  363. local a = {}
  364. for i = 1, 100 do a[i] = i end
  365. debug.sethook(function () count = count + 1 end, "", 1)
  366. local t = {table.unpack(a)}
  367. assert(#t == 100)
  368. t = {table.unpack(a, 1, 3)}
  369. assert(#t == 3)
  370. t = {f(table.unpack(a, 1, 30))}
  371. assert(#t == 31)
  372. end
  373. -- testing access to function arguments
  374. local function collectlocals (level)
  375. local tab = {}
  376. for i = 1, math.huge do
  377. local n, v = debug.getlocal(level + 1, i)
  378. if not (n and string.find(n, "^[a-zA-Z0-9_]+$")) then
  379. break -- consider only real variables
  380. end
  381. tab[n] = v
  382. end
  383. return tab
  384. end
  385. local X = nil
  386. a = {}
  387. function a:f (a, b, ...) local arg = {...}; local c = 13 end
  388. debug.sethook(function (e)
  389. assert(e == "call")
  390. dostring("XX = 12") -- test dostring inside hooks
  391. -- testing errors inside hooks
  392. assert(not pcall(load("a='joao'+1")))
  393. debug.sethook(function (e, l)
  394. assert(debug.getinfo(2, "l").currentline == l)
  395. local f,m,c = debug.gethook()
  396. assert(e == "line")
  397. assert(m == 'l' and c == 0)
  398. debug.sethook(nil) -- hook is called only once
  399. assert(not X) -- check that
  400. X = collectlocals(2)
  401. end, "l")
  402. end, "c")
  403. a:f(1,2,3,4,5)
  404. assert(X.self == a and X.a == 1 and X.b == 2 and X.c == nil)
  405. assert(XX == 12)
  406. assert(not debug.gethook())
  407. _G.XX = nil
  408. -- testing access to local variables in return hook (bug in 5.2)
  409. do
  410. local X = false
  411. local function foo (a, b, ...)
  412. do local x,y,z end
  413. local c, d = 10, 20
  414. return
  415. end
  416. local function aux ()
  417. if debug.getinfo(2).name == "foo" then
  418. X = true -- to signal that it found 'foo'
  419. local tab = {a = 100, b = 200, c = 10, d = 20}
  420. for n, v in pairs(collectlocals(2)) do
  421. assert(tab[n] == v)
  422. tab[n] = undef
  423. end
  424. assert(next(tab) == nil) -- 'tab' must be empty
  425. end
  426. end
  427. debug.sethook(aux, "r"); foo(100, 200); debug.sethook()
  428. assert(X)
  429. end
  430. local function eqseq (t1, t2)
  431. assert(#t1 == #t2)
  432. for i = 1, #t1 do
  433. assert(t1[i] == t2[i])
  434. end
  435. end
  436. do print("testing inspection of parameters/returned values")
  437. local on = false
  438. local inp, out
  439. local function hook (event)
  440. if not on then return end
  441. local ar = debug.getinfo(2, "ruS")
  442. local t = {}
  443. for i = ar.ftransfer, ar.ftransfer + ar.ntransfer - 1 do
  444. local _, v = debug.getlocal(2, i)
  445. t[#t + 1] = v
  446. end
  447. if event == "return" then
  448. out = t
  449. else
  450. inp = t
  451. end
  452. end
  453. debug.sethook(hook, "cr")
  454. on = true; math.sin(3); on = false
  455. eqseq(inp, {3}); eqseq(out, {math.sin(3)})
  456. on = true; select(2, 10, 20, 30, 40); on = false
  457. eqseq(inp, {2, 10, 20, 30, 40}); eqseq(out, {20, 30, 40})
  458. local function foo (a, ...) return ... end
  459. local function foo1 () on = not on; return foo(20, 10, 0) end
  460. foo1(); on = false
  461. eqseq(inp, {20}); eqseq(out, {10, 0})
  462. debug.sethook()
  463. end
  464. -- testing upvalue access
  465. local function getupvalues (f)
  466. local t = {}
  467. local i = 1
  468. while true do
  469. local name, value = debug.getupvalue(f, i)
  470. if not name then break end
  471. assert(not t[name])
  472. t[name] = value
  473. i = i + 1
  474. end
  475. return t
  476. end
  477. local a,b,c = 1,2,3
  478. local function foo1 (a) b = a; return c end
  479. local function foo2 (x) a = x; return c+b end
  480. assert(not debug.getupvalue(foo1, 3))
  481. assert(not debug.getupvalue(foo1, 0))
  482. assert(not debug.setupvalue(foo1, 3, "xuxu"))
  483. local t = getupvalues(foo1)
  484. assert(t.a == nil and t.b == 2 and t.c == 3)
  485. t = getupvalues(foo2)
  486. assert(t.a == 1 and t.b == 2 and t.c == 3)
  487. assert(debug.setupvalue(foo1, 1, "xuxu") == "b")
  488. assert(({debug.getupvalue(foo2, 3)})[2] == "xuxu")
  489. -- upvalues of C functions are always named "" (the empty string)
  490. assert(debug.getupvalue(string.gmatch("x", "x"), 1) == "")
  491. -- testing count hooks
  492. local a=0
  493. debug.sethook(function (e) a=a+1 end, "", 1)
  494. a=0; for i=1,1000 do end; assert(1000 < a and a < 1012)
  495. debug.sethook(function (e) a=a+1 end, "", 4)
  496. a=0; for i=1,1000 do end; assert(250 < a and a < 255)
  497. local f,m,c = debug.gethook()
  498. assert(m == "" and c == 4)
  499. debug.sethook(function (e) a=a+1 end, "", 4000)
  500. a=0; for i=1,1000 do end; assert(a == 0)
  501. do
  502. debug.sethook(print, "", 2^24 - 1) -- count upperbound
  503. local f,m,c = debug.gethook()
  504. assert(({debug.gethook()})[3] == 2^24 - 1)
  505. end
  506. debug.sethook()
  507. local g, g1
  508. -- tests for tail calls
  509. local function f (x)
  510. if x then
  511. assert(debug.getinfo(1, "S").what == "Lua")
  512. assert(debug.getinfo(1, "t").istailcall == true)
  513. local tail = debug.getinfo(2)
  514. assert(tail.func == g1 and tail.istailcall == true)
  515. assert(debug.getinfo(3, "S").what == "main")
  516. print"+"
  517. end
  518. end
  519. assert(debug.getinfo(print, 't').istailcall == false)
  520. assert(debug.getinfo(print, 't').extraargs == 0)
  521. function g(x) return f(x) end
  522. function g1(x) g(x) end
  523. local function h (x) local f=g1; return f(x) end
  524. h(true)
  525. local b = {}
  526. debug.sethook(function (e) table.insert(b, e) end, "cr")
  527. h(false)
  528. debug.sethook()
  529. local res = {"return", -- first return (from sethook)
  530. "call", "tail call", "call", "tail call",
  531. "return", "return",
  532. "call", -- last call (to sethook)
  533. }
  534. for i = 1, #res do assert(res[i] == table.remove(b, 1)) end
  535. b = 0
  536. debug.sethook(function (e)
  537. if e == "tail call" then
  538. b = b + 1
  539. assert(debug.getinfo(2, "t").istailcall == true)
  540. else
  541. assert(debug.getinfo(2, "t").istailcall == false)
  542. end
  543. end, "c")
  544. h(false)
  545. debug.sethook()
  546. assert(b == 2) -- two tail calls
  547. local lim = _soft and 3000 or 30000
  548. local function foo (x)
  549. if x==0 then
  550. assert(debug.getinfo(2).what == "main")
  551. local info = debug.getinfo(1)
  552. assert(info.istailcall == true and info.func == foo)
  553. else return foo(x-1)
  554. end
  555. end
  556. foo(lim)
  557. print"+"
  558. -- testing local function information
  559. co = load[[
  560. local A = function ()
  561. return x
  562. end
  563. return
  564. ]]
  565. local a = 0
  566. -- 'A' should be visible to debugger only after its complete definition
  567. debug.sethook(function (e, l)
  568. if l == 3 then a = a + 1; assert(debug.getlocal(2, 1) == "(temporary)")
  569. elseif l == 4 then a = a + 1; assert(debug.getlocal(2, 1) == "A")
  570. end
  571. end, "l")
  572. co() -- run local function definition
  573. debug.sethook() -- turn off hook
  574. assert(a == 2) -- ensure all two lines where hooked
  575. -- testing traceback
  576. assert(debug.traceback(print) == print)
  577. assert(debug.traceback(print, 4) == print)
  578. assert(string.find(debug.traceback("hi", 4), "^hi\n"))
  579. assert(string.find(debug.traceback("hi"), "^hi\n"))
  580. assert(not string.find(debug.traceback("hi"), "'debug.traceback'"))
  581. assert(string.find(debug.traceback("hi", 0), "'traceback'"))
  582. assert(string.find(debug.traceback(), "^stack traceback:\n"))
  583. do -- C-function names in traceback
  584. local st, msg = (function () return pcall end)()(debug.traceback)
  585. assert(st == true and string.find(msg, "pcall"))
  586. end
  587. -- testing nparams, nups e isvararg
  588. local t = debug.getinfo(print, "u")
  589. assert(t.isvararg == true and t.nparams == 0 and t.nups == 0)
  590. t = debug.getinfo(function (a,b,c) end, "u")
  591. assert(t.isvararg == false and t.nparams == 3 and t.nups == 0)
  592. t = debug.getinfo(function (a,b,...) return t[a] end, "u")
  593. assert(t.isvararg == true and t.nparams == 2 and t.nups == 1)
  594. t = debug.getinfo(1) -- main
  595. assert(t.isvararg == true and t.nparams == 0 and t.nups == 1 and
  596. debug.getupvalue(t.func, 1) == "_ENV")
  597. t = debug.getinfo(math.sin) -- C function
  598. assert(t.isvararg == true and t.nparams == 0 and t.nups == 0)
  599. t = debug.getinfo(string.gmatch("abc", "a")) -- C closure
  600. assert(t.isvararg == true and t.nparams == 0 and t.nups > 0)
  601. -- testing debugging of coroutines
  602. local function checktraceback (co, p, level)
  603. local tb = debug.traceback(co, nil, level)
  604. local i = 0
  605. for l in string.gmatch(tb, "[^\n]+\n?") do
  606. assert(i == 0 or string.find(l, p[i]))
  607. i = i+1
  608. end
  609. assert(p[i] == undef)
  610. end
  611. local function f (n)
  612. if n > 0 then f(n-1)
  613. else coroutine.yield() end
  614. end
  615. local co = coroutine.create(f)
  616. coroutine.resume(co, 3)
  617. checktraceback(co, {"yield", "db.lua", "db.lua", "db.lua", "db.lua"})
  618. checktraceback(co, {"db.lua", "db.lua", "db.lua", "db.lua"}, 1)
  619. checktraceback(co, {"db.lua", "db.lua", "db.lua"}, 2)
  620. checktraceback(co, {"db.lua"}, 4)
  621. checktraceback(co, {}, 40)
  622. co = coroutine.create(function (x)
  623. local a = 1
  624. coroutine.yield(debug.getinfo(1, "l"))
  625. coroutine.yield(debug.getinfo(1, "l").currentline)
  626. return a
  627. end)
  628. local tr = {}
  629. local foo = function (e, l) if l then table.insert(tr, l) end end
  630. debug.sethook(co, foo, "lcr")
  631. local _, l = coroutine.resume(co, 10)
  632. local x = debug.getinfo(co, 1, "lfLS")
  633. assert(x.currentline == l.currentline and x.activelines[x.currentline])
  634. assert(type(x.func) == "function")
  635. for i=x.linedefined + 1, x.lastlinedefined do
  636. assert(x.activelines[i])
  637. x.activelines[i] = undef
  638. end
  639. assert(next(x.activelines) == nil) -- no 'extra' elements
  640. assert(not debug.getinfo(co, 2))
  641. local a,b = debug.getlocal(co, 1, 1)
  642. assert(a == "x" and b == 10)
  643. a,b = debug.getlocal(co, 1, 2)
  644. assert(a == "a" and b == 1)
  645. debug.setlocal(co, 1, 2, "hi")
  646. assert(debug.gethook(co) == foo)
  647. assert(#tr == 2 and
  648. tr[1] == l.currentline-1 and tr[2] == l.currentline)
  649. a,b,c = pcall(coroutine.resume, co)
  650. assert(a and b and c == l.currentline+1)
  651. checktraceback(co, {"yield", "in function <"})
  652. a,b = coroutine.resume(co)
  653. assert(a and b == "hi")
  654. assert(#tr == 4 and tr[4] == l.currentline+2)
  655. assert(debug.gethook(co) == foo)
  656. assert(not debug.gethook())
  657. checktraceback(co, {})
  658. -- check get/setlocal in coroutines
  659. co = coroutine.create(function (x)
  660. local a, b = coroutine.yield(x)
  661. assert(a == 100 and b == nil)
  662. return x
  663. end)
  664. a, b = coroutine.resume(co, 10)
  665. assert(a and b == 10)
  666. a, b = debug.getlocal(co, 1, 1)
  667. assert(a == "x" and b == 10)
  668. assert(not debug.getlocal(co, 1, 5))
  669. assert(debug.setlocal(co, 1, 1, 30) == "x")
  670. assert(not debug.setlocal(co, 1, 5, 40))
  671. a, b = coroutine.resume(co, 100)
  672. assert(a and b == 30)
  673. -- check traceback of suspended (or dead with error) coroutines
  674. function f(i)
  675. if i == 0 then error(i)
  676. else coroutine.yield(); f(i-1)
  677. end
  678. end
  679. co = coroutine.create(function (x) f(x) end)
  680. a, b = coroutine.resume(co, 3)
  681. t = {"'yield'", "'f'", "in function <"}
  682. while coroutine.status(co) == "suspended" do
  683. checktraceback(co, t)
  684. a, b = coroutine.resume(co)
  685. table.insert(t, 2, "'f'") -- one more recursive call to 'f'
  686. end
  687. t[1] = "'error'"
  688. checktraceback(co, t)
  689. -- test accessing line numbers of a coroutine from a resume inside
  690. -- a C function (this is a known bug in Lua 5.0)
  691. local function g(x)
  692. coroutine.yield(x)
  693. end
  694. local function f (i)
  695. debug.sethook(function () end, "l")
  696. for j=1,1000 do
  697. g(i+j)
  698. end
  699. end
  700. local co = coroutine.wrap(f)
  701. co(10)
  702. pcall(co)
  703. pcall(co)
  704. assert(type(debug.getregistry()) == "table")
  705. -- test tagmethod information
  706. local a = {}
  707. local function f (t)
  708. local info = debug.getinfo(1);
  709. assert(info.namewhat == "metamethod")
  710. a.op = info.name
  711. return info.name
  712. end
  713. setmetatable(a, {
  714. __index = f; __add = f; __div = f; __mod = f; __concat = f; __pow = f;
  715. __mul = f; __idiv = f; __unm = f; __len = f; __sub = f;
  716. __shl = f; __shr = f; __bor = f; __bxor = f;
  717. __eq = f; __le = f; __lt = f; __unm = f; __len = f; __band = f;
  718. __bnot = f;
  719. })
  720. local b = setmetatable({}, getmetatable(a))
  721. assert(a[3] == "index" and a^3 == "pow" and a..a == "concat")
  722. assert(a/3 == "div" and 3%a == "mod")
  723. assert(a+3 == "add" and 3-a == "sub" and a*3 == "mul" and
  724. -a == "unm" and #a == "len" and a&3 == "band")
  725. assert(a + 30000 == "add" and a - 3.0 == "sub" and a * 3.0 == "mul" and
  726. -a == "unm" and #a == "len" and a & 3 == "band")
  727. assert(a|3 == "bor" and 3~a == "bxor" and a<<3 == "shl" and a>>1 == "shr")
  728. assert (a==b and a.op == "eq")
  729. assert (a>=b and a.op == "le")
  730. assert ("x">=a and a.op == "le")
  731. assert (a>b and a.op == "lt")
  732. assert (a>10 and a.op == "lt")
  733. assert(~a == "bnot")
  734. do -- testing for-iterator name
  735. local function f()
  736. assert(debug.getinfo(1).name == "for iterator")
  737. end
  738. for i in f do end
  739. end
  740. do -- testing debug info for finalizers
  741. local name = nil
  742. -- create a piece of garbage with a finalizer
  743. setmetatable({}, {__gc = function ()
  744. local t = debug.getinfo(1) -- get function information
  745. assert(t.namewhat == "metamethod")
  746. name = t.name
  747. end})
  748. -- repeat until previous finalizer runs (setting 'name')
  749. repeat local a = {} until name
  750. assert(name == "__gc")
  751. end
  752. do
  753. print("testing traceback sizes")
  754. local function countlines (s)
  755. return select(2, string.gsub(s, "\n", ""))
  756. end
  757. local function deep (lvl, n)
  758. if lvl == 0 then
  759. return (debug.traceback("message", n))
  760. else
  761. return (deep(lvl-1, n))
  762. end
  763. end
  764. local function checkdeep (total, start)
  765. local s = deep(total, start)
  766. local rest = string.match(s, "^message\nstack traceback:\n(.*)$")
  767. local cl = countlines(rest)
  768. -- at most 10 lines in first part, 11 in second, plus '...'
  769. assert(cl <= 10 + 11 + 1)
  770. local brk = string.find(rest, "%.%.%.\t%(skip")
  771. if brk then -- does message have '...'?
  772. local rest1 = string.sub(rest, 1, brk)
  773. local rest2 = string.sub(rest, brk, #rest)
  774. assert(countlines(rest1) == 10 and countlines(rest2) == 11)
  775. else
  776. assert(cl == total - start + 2)
  777. end
  778. end
  779. for d = 1, 51, 10 do
  780. for l = 1, d do
  781. -- use coroutines to ensure complete control of the stack
  782. coroutine.wrap(checkdeep)(d, l)
  783. end
  784. end
  785. end
  786. print("testing debug functions on chunk without debug info")
  787. local prog = [[-- program to be loaded without debug information (strip)
  788. local debug = require'debug'
  789. local a = 12 -- a local variable
  790. local n, v = debug.getlocal(1, 1)
  791. assert(n == "(temporary)" and v == debug) -- unknown name but known value
  792. n, v = debug.getlocal(1, 2)
  793. assert(n == "(temporary)" and v == 12) -- unknown name but known value
  794. -- a function with an upvalue
  795. local f = function () local x; return a end
  796. n, v = debug.getupvalue(f, 1)
  797. assert(n == "(no name)" and v == 12)
  798. assert(debug.setupvalue(f, 1, 13) == "(no name)")
  799. assert(a == 13)
  800. local t = debug.getinfo(f)
  801. assert(t.name == nil and t.linedefined > 0 and
  802. t.lastlinedefined == t.linedefined and
  803. t.short_src == "?")
  804. assert(debug.getinfo(1).currentline == -1)
  805. t = debug.getinfo(f, "L").activelines
  806. assert(next(t) == nil) -- active lines are empty
  807. -- dump/load a function without debug info
  808. f = load(string.dump(f))
  809. t = debug.getinfo(f)
  810. assert(t.name == nil and t.linedefined > 0 and
  811. t.lastlinedefined == t.linedefined and
  812. t.short_src == "?")
  813. assert(debug.getinfo(1).currentline == -1)
  814. return a
  815. ]]
  816. -- load 'prog' without debug info
  817. local f = assert(load(string.dump(load(prog), true)))
  818. assert(f() == 13)
  819. do -- bug in 5.4.0: line hooks in stripped code
  820. local function foo ()
  821. local a = 1
  822. local b = 2
  823. return b
  824. end
  825. local s = load(string.dump(foo, true))
  826. local line = true
  827. debug.sethook(function (e, l)
  828. assert(e == "line")
  829. line = l
  830. end, "l")
  831. assert(s() == 2); debug.sethook(nil)
  832. assert(line == nil) -- hook called without debug info for 1st instruction
  833. end
  834. do -- tests for 'source' in binary dumps
  835. local prog = [[
  836. return function (x)
  837. return function (y)
  838. return x + y
  839. end
  840. end
  841. ]]
  842. local name = string.rep("x", 1000)
  843. local p = assert(load(prog, name))
  844. -- load 'p' as a binary chunk with debug information
  845. local c = string.dump(p)
  846. assert(#c > 1000 and #c < 2000) -- no repetition of 'source' in dump
  847. local f = assert(load(c))
  848. local g = f()
  849. local h = g(3)
  850. assert(h(5) == 8)
  851. assert(debug.getinfo(f).source == name and -- all functions have 'source'
  852. debug.getinfo(g).source == name and
  853. debug.getinfo(h).source == name)
  854. -- again, without debug info
  855. local c = string.dump(p, true)
  856. assert(#c < 500) -- no 'source' in dump
  857. local f = assert(load(c))
  858. local g = f()
  859. local h = g(30)
  860. assert(h(50) == 80)
  861. assert(debug.getinfo(f).source == '=?' and -- no function has 'source'
  862. debug.getinfo(g).source == '=?' and
  863. debug.getinfo(h).source == '=?')
  864. end
  865. print"OK"