Q: How to debug the "Upvalue" information of "Closure"?
A:
--[[Debug.getupvalue (f, up) returns the first name and value of the "Up" "upvalue" of the function ("Closure") "F". Lua numbers the "upvalues" in the order in which they appear in the anonymous function. Returns "Nil" if the specified "Up" index is out of bounds. A variable name that begins with ' (') denotes a variable with no name (such as a control variable used for loop control, or a block of code that removes debugging information). Debug.setupvalue (f, up, value) is relative to the function of "debug.setupvalue ()" and sets the value of the "Up" upvalue "of the function" F "(" Closure ") to" value ". The function returns the name of the "Upvalue" being set. Returns "Nil" if the specified "Up" index is out of bounds. Note: Gets and sets whether "Upvalue" and "Closure" are called (whether on the call stack) regardless. ]]--"Closure". function newcounter () Localn =0 LocalK =0 return function () K = N n = n +1 returnNEndEndCounter = Newcounter ()Print(Counter ())Print(Counter ())at this point, "K" is 1 and "N" is 2. Locali =1RepeatName, val =Debug. Getupvalue (counter, i)ifName Then Print("Index", I, Name,"=", Val)--Output the names and values of two "upvalues" in turn. if(Name = ="n") Then Debug. Setupvalue (Counter,2,Ten)--Set the value of "n" to 10. Endi = i +1 Enduntil notName--At this point the value of "n" is set to 10. Print(Counter ())--After this call, the value of "n" is added to 1, which becomes 11. --[[results:1 2 index 1 k = 1 index 2 n = 2 each]]--[[debug.upvaluejoin (F1, N1, F2, N2) let the "Closure" and "F1" of "N1" and "Upvalue" refer to "Closure" and "F2" of "N2" "Upvalue". Debug.upvalueid (f, N) returns the identifier for the "n" "Upvalue" of the specified "Closure" "F" (a lightweight user data with the identifier unique for each "Upvalue"). This identifier allows the program to check whether two different "Closure" share the same "upvalue (s)". ]] function newcounter() Localn =0 LocalK =0 return function () K = N n = n +1 returnNEndEndCounter = Newcounter () function newCounter1() Localn =0 LocalK =0 return function () K = N n = n +1 returnNEndEndCounter1 = NewCounter1 ()-Each "Upvalue" has its own unique ID. Print(Debug. Upvalueid (Counter,1))- userdata:00559300Print(Debug. Upvalueid (Counter,2))- userdata:00559348Print(Debug. Upvalueid (Counter1,1))- Userdata:005593d8Print(Debug. Upvalueid (Counter1,2))- userdata:00559420--Let the first "upvalue" of "counter" refer to the second "upvalue" of "Counter1". Debug. Upvaluejoin (Counter,1, Counter1,2)--The first "upvalue" of "counter" is the same as the ID of the second "upvalue" of "Counter1". Print(Debug. Upvalueid (Counter,1))- userdata:00559420Print(Debug. Upvalueid (Counter,2))- userdata:00559348Print(Debug. Upvalueid (Counter1,1))- Userdata:005593d8Print(Debug. Upvalueid (Counter1,2))- userdata:00559420
Q: How to track the operation of the program?
A:
--[[Debug.sethook ([Thread,] hook, Mask [, Count]) sets the function "hook" to the hook function of thread "thread". "Mask" determines when the hook function is triggered, and "count" determines when the hook function is called in extra time. "Thread" defaults to the current thread. The "Count" default is 0, and the hook function will call the hook function once per run "count" instruction, passing the event "count" to the hook function. "Mask" can be specified as one or more of the following values: ' C ': whenever Lua invokes a function, calls the hook function, passes the event "call" to the hook function, or "tail call"; ' R ': Whenever Lua returns from within a function, calls the hook function to the hook The function passes the event "return"; ' l ': whenever Lua enters a new line, call the hook function and pass the event "line" to the hook function. When the hook function is called, the first argument is the event that triggered the call. For the "line" event, there is a second argument, which is the current row number. function does not pass the parameter, the hook function is closed. ]]Debug. Sethook (Print,"CRL") function foo() LocalA =1EndLocalx =1Foo ()Localy =1--[[Results:return Nil Line 5, line 3, line 7, line 8, nil line 4 Line 5 return nil Line 9 return nil return nil]]--[[Debug.gethook ([thread]) returns the memory address of the hook function, the mask of the hook function, and "Debug.sethook ()" As the "count" set by the hook function. ]]Debug. Sethook (Print,"L",9)Print(Debug. Gethook ())Debug. Sethook ()--Close the hook function. Print(Debug. Gethook ())--There is no hook function to get anything. --[[results:line 2 function:013d1a70 L 9 line 3 Nil 0]
Q: How can I view the registry information for Lua?
A:
--[[ debug.getregistry() 函数返回Lua的"registry"。]]
Q: How do I create a program parser?
A: The mode library can be used for other tasks besides the mode, this common task is analysis. For a real-time analysis, it is best to use the C interface to complete. The LUA calls used by each hook function are too expensive and often result in inaccurate measurements. However, for the counting analysis, LUA is well qualified.
--A Small Basic parser that records the number of functions that are called in a program. LocalCounters = {}--Key-value: function-CountLocalNames = {}--Key-value: Functions-function nameLocal function hook() Localf =Debug. GetInfo (2,"F"). Func--Gets the called function itself. ifCOUNTERS[F] = =Nil Then --if it is called for the first time. COUNTERS[F] =1NAMES[F] =Debug. GetInfo (2,"Sn")--Gets the function information. Else -If previously recorded, this only increases its count. COUNTERS[F] = Counters[f] +1 EndEndLocalf =assert(Load("Print (' Hello world! ')"))Debug. Sethook (Hook,"C")--Call the hook function when the function is called. F ()Debug. Sethook ()--Close the hook function. --Get results. function getname(func) Localn = names[func]ifN.what = ="C" Then --If it is a C function, only its name is returned. returnN.nameEnd --If it is not a C function, return the form "[File]:line". LocalLOC =string. Format ("[%s]:%s], N.SHORT_SRC, n.linedefined)ifN.namewhat ~="" Then --If it is not an anonymous function, return a reasonable name, "[File]:line (Name)". return string. Format ("%s (%s)", LOC, N.name)Else --Otherwise, only the "[File]:line" form is returned. return string. Format ('%s ', loc)EndEnd forFunc, Countinch Pairs(Counters) Do Print(GetName (func), count)End--[[Results:hello world! [[String] Print (' Hello world! ') "]]:0 (f) 1 print 1 Sethook 1 nil 1 <--This doesn't know what the function is. ]]
Additional:
1, in the hook function, you can call "Debug.getinfo ()", specify the stack level of 2, to get the details of the running function ("Debug.getinfo ()" The stack level is 0, the hook function stack level is 1).
2. A sophisticated tracker that prints file names and line numbers,
function trace(event, line) localdebug.getinfo(2).short_src print":" .. line)enddebug"l")
Quick Master Lua 5.3--Debug Library (2)