339 lines
15 KiB
HTML
Executable File
339 lines
15 KiB
HTML
Executable File
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
|
|
|
<html xmlns="http://www.w3.org/1999/xhtml">
|
|
|
|
<head>
|
|
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
|
|
<title>LOOP: Code Inspector</title>
|
|
<style type="text/css" media="all"><!--
|
|
@import "../../loop.css";
|
|
@import "../../layout1.css";
|
|
--></style>
|
|
</head>
|
|
|
|
<body>
|
|
|
|
<div id="Header">Class Models for Lua</div>
|
|
<div id="Logo"><img alt="small (1K)" src="../../small.gif" height="70"></div>
|
|
|
|
<div id="Menu">
|
|
<div class="outside"><div class="inside"><ul>
|
|
<li><a href="../../index.html", title="">Home</a></li>
|
|
<li><a href="../../release/index.html", title="Installation">Install</a></li>
|
|
<li><a href="../../manual/index.html", title="User Manual">Manual</a></li>
|
|
<li><a href="../index.html", title="Class Library">Library</a>
|
|
<div class="outside"><div class="inside"><ul>
|
|
<li><a href="../overview.html#collection", title="Collections">collection</a>
|
|
</li>
|
|
<li><a href="../overview.html#compiler", title="Compiling">compiler</a>
|
|
</li>
|
|
<li><a href="../overview.html#debug", title="Debugging">debug</a>
|
|
</li>
|
|
<li><a href="../overview.html#object", title="Objects">object</a>
|
|
</li>
|
|
<li><a href="../overview.html#serial", title="Serialization">serial</a>
|
|
</li>
|
|
<li><a href="../overview.html#thread", title="Threading">thread</a>
|
|
</li>
|
|
</ul></div></div>
|
|
</li>
|
|
<li><a href="../../contact.html", title="Contact People">Contact</a></li>
|
|
<li><a href="http://luaforge.net/projects/oil/", title="Project at LuaForge">LuaForge</a></li>
|
|
</ul></div></div>
|
|
|
|
</div>
|
|
|
|
<div class="content">
|
|
<h1>Code Inspector</h1>
|
|
<h2><code>loop.debug.Inspector</code></h2><br>
|
|
<p>Class of objects that implement a command-line prompt to access the lexical scope of a point in an application.
|
|
The command-line prompt also allows to navigate through active co-rotines and access the lexical scope of the point they are currently executing.
|
|
It is also possible to navigate to inactive functions in order to access the current value of their upvalues.
|
|
This class is useful for implementation of command-line debugging mechanisms.</p>
|
|
|
|
<p>Each object instance implements an environment that retrieves the value of variables and upvalues of a given point in the code.
|
|
The method <code>stop</code> sets up the environment to access the lexical scope of the point it was called.
|
|
The access is provided by an interactive prompt similar to the one provided by the Lua stand-alone interpreter.
|
|
Although it provides additional commands to navigate to different points of the running application like active co-routines.</p>
|
|
|
|
<h2>Behavior</h2>
|
|
|
|
<h3>Fields</h3>
|
|
|
|
<dl>
|
|
|
|
<dt><code><b>active</b></code></dt>
|
|
<dd>
|
|
Defines if the inspector instance is active or not.
|
|
If this field evaluates to <code>false</code> then all calls to method <code>stop</code> have no effect.
|
|
The default value for this field is <code>true</code>.
|
|
</dd>
|
|
|
|
<dt><code><b>input</b></code></dt>
|
|
<dd>
|
|
Defines the object used to read commands inserted through the command prompt.
|
|
The object must provide the method <code>write</code> like Lua file handlers.
|
|
The default value for this field is the standard input (<i>i.e.</i> <code>io.stdin</code>).
|
|
</dd>
|
|
|
|
<dt><code><b>viewer</b></code></dt>
|
|
<dd>
|
|
Defines the object used to print out messages of the command prompt.
|
|
The object must provide the same API of instances of <code><a href="Viewer.html">Viewer</a></code>.
|
|
The default value for this field is the <code>Viewer</code> class itself.
|
|
</dd>
|
|
|
|
</dl>
|
|
|
|
<h3>Methods</h3>
|
|
|
|
<dl>
|
|
|
|
<dt><code><b>allbreaks</b>()</code></dt>
|
|
<dd>
|
|
Return an iterator that iterates over all registered break point marks.
|
|
The iteration variables are the source name pattern and the source code line.
|
|
</dd>
|
|
|
|
<dt><code><b>removebreak</b>(file, line)</code></dt>
|
|
<dd>
|
|
Unregisters the break point marks from line <code>line</code> of all Lua chucks which source name ends with the string <code>file</code>.
|
|
</dd>
|
|
|
|
<dt><code><b>setbreak</b>(file, line)</code></dt>
|
|
<dd>
|
|
Registers a break point mark in line <code>line</code> of all Lua chucks which source name ends with the string <code>file</code>.
|
|
When the execution of the program reaches a break point mark the inspection console is open in that point.
|
|
</dd>
|
|
|
|
<dt><code><b>stop</b>([level])</code></dt>
|
|
<dd>
|
|
Executes the command-line prompt used to inspect the current executing code.
|
|
Parameter <code>level</code> defines the stack level of the function to be inspected.
|
|
Level 1 is the function that called <code>stop</code>, level 2 is the function above, and so on.
|
|
The command-line prompt executes Lua code as if the code was executed inside the function being inspected.
|
|
Additionally it also provides the commands described below.
|
|
As a shortcut, the commands can be invoked without arguments by typing its name only.
|
|
<dl>
|
|
<dt><code><b>see</b>(...)</code></dt>
|
|
<dd>
|
|
Command that writes the textual representation of all its arguments.
|
|
This command uses the object in field <code>viewer</code> to generate the textual representations.
|
|
</dd>
|
|
<dt><code><b>loc</b>([name, value])</code></dt>
|
|
<dd>
|
|
Command used to access the local variables avaliable in the inspected scope.
|
|
When used with no arguments it writes the textual representation of all local variables avaliable.
|
|
If first argument is provided it just returns the value of the local variable with name <code>name</code>.
|
|
If both arguments are provided then it changes the value of the local variable with name <code>name</code> to the value of <code>value</code>.
|
|
If there is no local variable with that name <code>name</code> the call has no effect.
|
|
</dd>
|
|
<dt><code><b>upv</b>([name, value])</code></dt>
|
|
<dd>
|
|
Command used to access the upvalues avaliable in the inspected scope.
|
|
When used with no arguments it writes the textual representation of all upvalues avaliable.
|
|
If first argument is provided it just returns the value of the upvalue with name <code>name</code>.
|
|
If both arguments are provided then it changes the value of the upvalue with name <code>name</code> to the value of <code>value</code>.
|
|
If there is no upvalue with that name <code>name</code> the call has no effect.
|
|
</dd>
|
|
<dt><code><b>env</b>([name, value])</code></dt>
|
|
<dd>
|
|
Command used to access the environment of the inspected scope.
|
|
When used with no arguments it writes the textual representation of all global variables avaliable.
|
|
If first argument is provided it just returns the value of the global variable with name <code>name</code>.
|
|
If both arguments are provided then it changes the value of the global variable with name <code>name</code> to the value of <code>value</code>.
|
|
If there is no global variable with that name <code>name</code> a new variable is created with the given value.
|
|
</dd>
|
|
<dt><code><b>lua</b>([name, value])</code></dt>
|
|
<dd>
|
|
Command used to access the default Lua global environment, <i>i.e.</i> the default value of <code>_G</code>.
|
|
When used with no arguments it writes the textual representation of the default Lua global state.
|
|
If first argument is provided it just returns the value of the global variable with name <code>name</code> from the default Lua global environment.
|
|
If both arguments are provided then it changes the value of the global variable with name <code>name</code> to the value of <code>value</code> in the default Lua global environment.
|
|
If there is no global variable in the default Lua global environment with that name <code>name</code> a new variable is created with the given value.
|
|
</dd>
|
|
<dt><code><b>goto</b>(where)</code></dt>
|
|
<dd>
|
|
Command used to change the inspected scope to the co-routine or function defined by argument <code>where</code>.
|
|
When nagivating to a function, no local variables are accessible.
|
|
To access local variables you have to nagivate to a co-routine executing the function and go up in the stack level until reach the desired function.
|
|
It is not possible to navigate to the main thread.
|
|
</dd>
|
|
<dt><code><b>goup</b>()</code></dt>
|
|
<dd>
|
|
Command used to change the inspected scope to the function one level up in the stack of the current thread.
|
|
</dd>
|
|
<dt><code><b>back</b>()</code></dt>
|
|
<dd>
|
|
Command used to go back to the previous inspected scope.
|
|
</dd>
|
|
<dt><code><b>hist</b>()</code></dt>
|
|
<dd>
|
|
Command that list all the scope changes already performed through the commands <code>goto</code> and <code>goup</code>.
|
|
</dd>
|
|
<dt><code><b>curr</b>()</code></dt>
|
|
<dd>
|
|
Command that shows the upper levels of the stack of the current inspected environment.
|
|
</dd>
|
|
<dt><code><b>done</b>()</code></dt>
|
|
<dd>
|
|
Command used to indicate the conclusion of the inspection and continue the execution.
|
|
</dd>
|
|
<dt><code><b>step</b>([kind])</code></dt>
|
|
<dd>
|
|
Command used to indicate the conclusion of the inspection and re-open the inspection console after execution of one more instruction of the source code.
|
|
If the parameter <code>kind</code> is <code>"in"</code> and the next instruction of the source code results in a function call then the inspection console is re-open at the first instruction of the called function's source code.
|
|
Additionally, if the parameter <code>kind</code> is <code>"out"</code> then the rest of the current function is executed and the inspection console is re-open at the first instruction after the current function returned.
|
|
</dd>
|
|
<dt><code><b>mkbp</b>(file, line)</code></dt>
|
|
<dd>
|
|
Command used to emulate method <code>setbreak</code> in the inspection console.
|
|
</dd>
|
|
<dt><code><b>rmbp</b>(file, line)</code></dt>
|
|
<dd>
|
|
Command used to emulate method <code>removebreak</code> in the inspection console.
|
|
</dd>
|
|
<dt><code><b>lsbp</b>()</code></dt>
|
|
<dd>
|
|
Command used to list all the break point marks currently registered.
|
|
</dd>
|
|
</dl>
|
|
</dd>
|
|
|
|
</dl>
|
|
|
|
<h3>Meta-Fields</h3>
|
|
|
|
<dl>
|
|
|
|
<dt><code><b>__index</b> = function</code></dt>
|
|
<dd>
|
|
Retrieves the values of the variables and upvalues accessible through the current inspected scope.
|
|
</dd>
|
|
|
|
<dt><code><b>__newindex</b> = function</code></dt>
|
|
<dd>
|
|
Changes the values of the variables and upvalues accessible through the current inspected scope.
|
|
</dd>
|
|
|
|
</dl>
|
|
|
|
<h2>Remarks</h2>
|
|
|
|
<ul>
|
|
<li>All names of fields and methods provided by the <code>Inspector</code> instance are always binded to their respective values and therefore hide any variables or upvalues with those names.
|
|
The same is true for the names of the commands provide by the command prompt that are listed in the description of method <code>stop</code>.
|
|
To access variables or upvalues with those names use commands <code>loc(</code><i>name [, value]</i><code>)</code>, <code>upv(</code><i>name [, value]</i><code>)</code>, <code>env(</code><i>name [, value]</i><code>)</code> and <code>lua(</code><i>name [, value]</i><code>)</code> to access respectively the value of local variables, upvalues global variables of the function's environment, and global variables of the Lua default global environment (<i>i.e.</i> <code>_G</code>).</li>
|
|
</ul>
|
|
|
|
<h2>Examples</h2>
|
|
|
|
<h3><a name="DiningPhilo">Dining philosophers problem analyzer</a></h3>
|
|
|
|
<pre>
|
|
inspector = require("loop.debug.Inspector")()
|
|
|
|
-- TIPS:
|
|
-- To check the state of all philosophers, type:
|
|
-- io.write("Forks = ") see(forks)
|
|
-- goto(P1) print("--> P1:") loc()
|
|
-- goto(P2) print("--> P2:") loc()
|
|
-- goto(P3) print("--> P3:") loc()
|
|
--
|
|
-- To remove deadlock condition, type:
|
|
-- forks = {true,true,true}
|
|
-- goto(P1) left,right = false,false
|
|
-- goto(P2) left,right = false,false
|
|
-- goto(P3) left,right = false,false
|
|
--
|
|
-- To avoid that philosophers die from starvation, type:
|
|
-- goto(P1) hunger = 0 goto(P2) hunger = 0 goto(P3) hunger = 0
|
|
|
|
local forks = { true, true, true }
|
|
|
|
function philo(lfork, rfork)
|
|
local hunger = 0
|
|
local left = false
|
|
local right = false
|
|
repeat
|
|
if hunger == 0 then
|
|
for i=1, math.random(5) do
|
|
coroutine.yield("thinking")
|
|
hunger = hunger + 1
|
|
end
|
|
else
|
|
hunger = hunger + 1
|
|
end
|
|
if not left then
|
|
if forks[lfork]
|
|
then left, forks[lfork] = true, false
|
|
else coroutine.yield("waiting")
|
|
end
|
|
end
|
|
if not right then
|
|
if forks[rfork]
|
|
then right, forks[rfork] = true, false
|
|
else coroutine.yield("waiting")
|
|
end
|
|
end
|
|
if left and right then
|
|
while hunger > 0 do
|
|
coroutine.yield("eating")
|
|
hunger = hunger - 1
|
|
end
|
|
left, forks[lfork] = false, true
|
|
right, forks[rfork] = false, true
|
|
else
|
|
if hunger > 10 then
|
|
coroutine.yield("starving")
|
|
end
|
|
end
|
|
until hunger > 10
|
|
return "dead"
|
|
end
|
|
|
|
P1 = coroutine.create(philo)
|
|
P2 = coroutine.create(philo)
|
|
P3 = coroutine.create(philo)
|
|
|
|
local locked = 0
|
|
local failed
|
|
math.randomseed(os.time())
|
|
repeat
|
|
locked = 0
|
|
for i, philo in pairs{ P1, P2, P3 } do
|
|
local ok, msg = coroutine.resume(philo, i, (i+1)%3)
|
|
print("P"..i, msg)
|
|
if ok then
|
|
if msg == "starving" then
|
|
print("STARVATION", "P"..i)
|
|
inspector:stop()
|
|
elseif msg == "waiting" then
|
|
locked = locked + 1
|
|
else
|
|
locked = 0
|
|
end
|
|
else
|
|
failed = true
|
|
end
|
|
if locked >= 3 then
|
|
print("DEADLOCK")
|
|
inspector:stop()
|
|
end
|
|
end
|
|
until failed
|
|
</pre>
|
|
|
|
</div>
|
|
|
|
<div class="content">
|
|
<p><small><strong>Copyright (C) 2004-2008 Tecgraf, PUC-Rio</strong></small></p>
|
|
<small>This project is currently being maintained by <a href="http://www.tecgraf.puc-rio.br">Tecgraf</a> at <a href="http://www.puc-rio.br">PUC-Rio</a>.</small>
|
|
</div>
|
|
|
|
|
|
|
|
</body>
|
|
|
|
</html>
|