Lua Debugging - Detect when the value of a variable changes - debugging

Is it possible to detect when the value of a variable has changed using the lua debug library.
Something like A callback function which would give details like the function in which the value was changed, previous value, etc.
Is such a thing possible?
I read about hooks, but I'm not sure hooks can be set to variables.

If you don't mind using a debugger, then some debuggers allow you to set Watch expressions, which will be triggered when the condition in the expression is true. I'll show how this can be done in MobDebug (it is using lua debug library, but there is no direct way to detect a variable change as far as I know).
Let say we have a script start.lua like the one below and want to detect where foo gets value 2:
print("Start")
local foo = 0
for i = 1, 3 do
local function bar()
print("In bar")
end
foo = i
print("Loop")
bar()
end
print("End")
Download mobdebug.lua and make it available to your scripts (the simplest way is to put it into the folder with your scripts).
Start the server using lua -e "require('mobdebug').listen()" command.
Start the client using lua -e "require('mobdebug').loop()" command.
You will see the prompt in the server window: '>'. Type load start.lua to load the script.
Type step and then step again. You will see "Paused at file start.lua line 3".
Let's see what the value of foo is. Type eval foo and you should see 0.
Now we can set up our watch. Type setw foo == 2. You can specify any Lua expression after setw command; the execution of your script will be stopped when the condition is evaluated as true.
Continue execution of the script using "run" command.
The watch now fires, which will show you the message like: "Paused at file start.lua line 8 (watch expression 1: [foo == 2])". This means that the previous expression changed the value of foo to 2 and the execution is stopped at line 8. You can then inspect your script and the current values (you can use "eval" and "exec" commands to run any Lua code to be evaluated in your script environment) to find what triggered the change.
The benefit of this approach is that you are not limited to monitoring table values and can specify any expression. The main disadvantage is that your script runs under a debugger and the expression is evaluated after each step, which may get really slow.

You can do this to a certain extent in Lua by using metatables and keeping a "proxy" table, and using the __newindex function call to detect attempts to add a variable.
This is covered here in the Programming in Lua book under the section "Tracking Table Accesses":
http://www.lua.org/pil/13.4.4.html
See Also
http://www.gammon.com.au/forum/?id=10887

Related

How to schedule puppet custom facts to execute every X hours?

I have a custom puppet fact (written in ruby) which executes a simple bash script. The script checks all files in the file system for world-readable permissions and returns results accordingly. The puppet fact checks the output of the script and returns "fail" if the script output is not null.
The problem is that the script is resource intensive and I don't want it to be executed every 30 minutes (client' puppet.conf: runinternval=1800).
I've tried using the "schedule" resource but because of the way puppet works, it only affects the class I'm using to evaluate the fact's output. Puppet facts are evaluated on each puppet run, regardless of anything else. (thus making them available for resources)
I've also tried to move the code that executes the bash script out from the fact and into the puppet class but it appears you cannot evaluate the output of a bash script (using "exec" type) and store it in a variable (again, because of the way puppet works).
I am now reduced to try and apply some kind of scheduling mechanism using Ruby language, and implement it in the fact. I've read a bit on PStore and right now this seems like a good direction.
Does anyone know how I can make a ruby script execute only during night? I cannot use crontab because the code will run by puppet.
Code snippet from the puppet class:
if $::myfact == 'fail' {
notify { "warning blah blah...":
loglevel => err,
schedule => 'night',
}
}
Code snippet from the puppet fact:
require 'facter'
Facter.add(:myfact) do
setcode do
if File.exists? '/usr/local/puppet/scripts/myscript.sh'
result = Facter::Util::Resolution.exec("/usr/local/puppet/scripts/myscript.sh")
if result != ''
puts "Result of myfact is: \n #{result}"
'fail'
end
end
end
end
Your custom fact can memorialize its result in a file somewhere on the system. When it is evaluated, it can compare the timestamp on that file to the current system time, and either read back the value or compute it freshly, as appropriate. That also allows you to defer updates (for instance, by touching the file) or to manually request re-evaluation (by deleting the file).
Consider, however, whether it makes sense to decouple the costly evaluation from fact gathering. Even if Facter only occasionally has to re-evaluate the fact from scratch, Facter -- and therefore Puppet -- will take a long time to perform those runs. You could consider instead using a scheduled job to perform the evaluation at whatever intervals you like, and have the custom fact always rely on cached results from the latest of those evaluations.

Pry (Ruby REPL): How can I turn automatic echo off

Since Ruby supports parallel assignments and automatic value return from functions, almost every assignment and method run ends up creating an output when working on REPLs like IRB and Pry.
Normally I prevent this echo effect by putting a semicolon at the end of each line. For instance:
JSON::parse(very_long_json_string);
This normally prevents REPL echo. But when working with very large enumerables even one mistake can generate enough output to make a mess on the screen and put all my useful command history out of memory before I have the reflex to hit the break.
Is there a way to turn this echo effect off by default in Pry? As mentioned in the comments below (#Stefan), the same can be achieved in IRB by setting conf.echo = false.
In IRB there is:
conf.echo = false
In Pry you could replace the print object with an empty proc:
_pry_.config.print = proc {}
You'll have to store the old print object in order to restore it.
In both cases, the result of the last expression is still available via _

How do I quickly inspect the value of an arbitrary variable in Xcode 4.6.x?

It seems reasonably widely acknowledged that it is slow to use the po command in Xcode 4.6.x. What are the options for inspecting the values of arbitrary variables unspecified at compile time (which rules out usage of NSLog()) which don't take > 15s?
Just set a breakpoint where you want to learn the variables' value. Once the program is paused, a summary of all the variables' value will appear on the Varibles view on the left-bottom of the screen. Here is a screenshot :
You can use the lldb commands:
p (int) myInt
po myObject
po myObject.memberObject
p (float) myObject.floatMember
Just a note, you could also use p instead of po in the newest version of Xcode. If you run the help -a in llb, it will present you with command aliases, below is a snippet of the commands you could use.
> (lldb) help -a
p -- ('expression --') Evaluate a C/ObjC/C++ expression in the current
program context, using user defined variables and variables
currently in scope.
po -- ('expression -o --') Evaluate a C/ObjC/C++ expression in the
current program context, using user defined variables and
variables currently in scope
print -- ('expression --') Evaluate a C/ObjC/C++ expression in the current
program context, using user defined variables and variables
currently in scope.
Turns out the answer is pretty simple: download Xcode 4.6.2 where LLDB debugging speed has been increased significantly. Note some discussion over here

How do I use Ruby debugger in Emacs?

I am writing Ruby in Emacs, but my Emacs skills are actually pretty low. What I can do, is open the project, TDD using M-x rinari-test, or play inferior Ruby in the second window using M-x run-ruby. Now I woul like to start using debugger from StdLib. I am able to summon it from irb by saying:
require 'debug'
Upon which I get into a prompt
(rdb:1)
but there my aptitude ends. I don't even know how to step into a file. Typing 'help' brought a screenful, but it didn't help me to finally start debugging my buggy gem. Online, everybody writes about things such as "rdebug" or "ruby-debug" or whatever which I firstly don't want to use and secondly, being a muggle, I am unable to install on my Debian. Please help!!!
You really need to try reading the output of help in the debugger. It explains the commands nicely.
For instance, for practice, try this at the command-line, not inside an editor/IDE:
ruby -rdebug -e 'p 1'
h
Ruby's debugger will output the help summary:
Debugger help v.-0.002b
Commands
b[reak] [file:|class:]<line|method>
b[reak] [class.]<line|method>
set breakpoint to some position
wat[ch] <expression> set watchpoint to some expression
cat[ch] (<exception>|off) set catchpoint to an exception
b[reak] list breakpoints
cat[ch] show catchpoint
del[ete][ nnn] delete some or all breakpoints
disp[lay] <expression> add expression into display expression list
undisp[lay][ nnn] delete one particular or all display expressions
c[ont] run until program ends or hit breakpoint
s[tep][ nnn] step (into methods) one line or till line nnn
n[ext][ nnn] go over one line or till line nnn
w[here] display frames
f[rame] alias for where
l[ist][ (-|nn-mm)] list program, - lists backwards
nn-mm lists given lines
up[ nn] move to higher frame
down[ nn] move to lower frame
fin[ish] return to outer frame
tr[ace] (on|off) set trace mode of current thread
tr[ace] (on|off) all set trace mode of all threads
q[uit] exit from debugger
v[ar] g[lobal] show global variables
v[ar] l[ocal] show local variables
v[ar] i[nstance] <object> show instance variables of object
v[ar] c[onst] <object> show constants of object
m[ethod] i[nstance] <obj> show methods of object
m[ethod] <class|module> show instance methods of class or module
th[read] l[ist] list all threads
th[read] c[ur[rent]] show current thread
th[read] [sw[itch]] <nnn> switch thread context to nnn
th[read] stop <nnn> stop thread nnn
th[read] resume <nnn> resume thread nnn
p expression evaluate expression and print its value
h[elp] print this help
<everything else> evaluate
The important commands to start with are s, n, c and b, and q.
s steps into a method.
n steps over a method.
c number runs (continue) until you reach line number.
b number sets a breakpoint on line number. After setting your breakpoints use c to continue running until that line is executed.
q exits the debugger.
Personally, I use the debugger gem. Others use PRY, which is similar to IRB, but with debugger-like extensions.
Knowing how to use a debugger is a good skill. There are problems you can trace down quickly using a debugger, that will take longer trying to use puts statements, because you can see what a variable contains interactively, or loop conditionally until a variable contains a certain value.

Setting a watch point in GDB

I am operating a huge code base and want to monitor a value of a particular variable (which is buried deep down inside one of the files)especially when it gets set to zero.
1) Variable does not belong to global scope .Is there a better option than to first set breakpoint into the function where it is defined and then set the watch point?
2) After trying the option in 1 I see that watch point gets deleted after a while saying its out of frame which used this .This way it adds to the tediousness of the procedure since I have to add it again and again?Any workarounds?
3) Is there a way to check ie watch if a particular variable is equal to 0( or any specific constant)?
want to monitor a value of a particular variable
Often this is not the best approach, especially in large codebases.
What you really likely want to do is understand the invariants, and assert that they are true on entry and exit to various parts of the code.
1) Variable does not belong to global scope .Is there a better option than to first set breakpoint into the function where it is defined and then set the watch point?
No. For automatic (stack) variables you have to be in the scope where the variable is "active".
What you can do is set a breakpoint on some line, and attach commands to that breakpoint that will set the watchpoint automatically, e.g.
(gdb) break foo.c:123
(gdb) commands 1
silent
watch some_local
continue
end
3) Is there a way to check ie watch if a particular variable is equal to 0
You can't do that with a watchpoint, but you can with a conditional breakpoint:
(gdb) break foo.c:234 if some_local == 0
I will assume that you are using Linux. You can try this:
The first step is to make the variable static, like:
static int myVar;
Then, after compiling your code using -ggdb, you must discover the address of the variable inside your binary, like so (I have used a real case as example):
readelf -s pdv | grep tmp | c++filt
In my situation, the output is:
47: 081c1474 4 OBJECT LOCAL DEFAULT 25 startProc(int)::tmp
The address in this case is 081c1474. Now you can set a watch point inside GDB:
watch *0x081c1474
Mind the "*0x" before the correct address.
I know this question is old, but I hope it helps anyway.

Resources