I don't know why I'm having so much trouble groking the documentation for the elisp debugger.
I see it has a commands to "step-into" (d). But for the life of me, I cannot see a step-out or step-over.
Can anyone help?
If I have this in the Backtrace buffer:
Debugger entered--returning value: 5047
line-beginning-position()
* c-parse-state()
* byte-code("...")
* c-guess-basic-syntax()
c-show-syntactic-information(nil)
call-interactively(c-show-syntactic-information)
...where do I put the cursor, and what key do I type, to step out of the parse-state() fn ? by that I mean, run until that fn returns, and then stop in the debugger again.
When debugging, I press ? and I see:
o edebug-step-out
f edebug-forward-sexp
h edebug-goto-here
I believe o (it is step-out) and f (like step over) are what you're looking for, though I also find h extremely useful.
'c' and 'j' work kind of like a step-out and step-over. When a flagged frame (indicated by "*") is encountered (the docs say "exited" but this doesn't seem to be how the debugger behaves), the debugger will be re-entered. When the top frame is flagged, they work like step-over; when it isn't, they work like step-out.
In your example backtrace, typing either will step out of line-beginning-position into c-parse-state. The frame flag should clear, so typing either a second time should step out of c-parse-state.
Hm. I, for one, prefer debug to edebug, but to each her own...
As to debug, I use d, c, e, and q.
If you do use debug, one thing to keep in mind, which can save time and effort, is that when you see a macro call (starts with#) you can just hit c to expand the macro -- there is normally no sense in digging into the macro expansion code (unless you wrote the macro and you are trying to debug it).
In particular, for dolist, there are two levels of macroexpansion to skip over using c: one for dolist and one for block.
HTH.
Related
I am trying to find out how to proper way to use RemoteChannel inside of a macro. In a function or the REPL, the following code works:
addprocs(3)
r = RemoteChannel(3)
#spawnat(3,put!(r,10))
fetch(r) # Gives 10
However, if I put that same stuff in a macro:
macro rrtest(src,val)
quote
r = RemoteChannel($(esc(src)))
#spawnat($(esc(src)), put!(r, $(esc(val))))
println(fetch(r))
end
end
and then call it with the same arguments
#rrtest(3,10)
then the REPL just stalls. Is there something wrong with using RemoteChannels like this?
macro rrtest(src,val)
quote
r = RemoteChannel($(esc(src))) #Using a `Future` here maybe be better
remotecall_wait(r_i->put!(r_i, $(esc(val))), $(esc(src)), r)
wait(r);
println(fetch(r))
end
end
The wait(r) should not be required -- fetch is supposed call wait when used on a Future or RemoteChannel.
But it does seem to be, sometimes.
Changing the #spawnat to a remotecall means you can pass in the r, without that, it gets. I think there are off things with how macro-hygine nests with closures created themself with macros. (#spawnat) creates closures inside another macro. It is awkaward to reasonabout.
In general I find #spawnat harder to reason about, than remote_call.
The reason it needs to be remotecall_wait is because otherwise, there is no garentee when its contents will run. Which means what is happening to r is itself unclear. I feel like it should be safe, but it does not seem to be.
I think because the waiting for r, rather than waiting for the remotecall that sets r is never certain to allow that remotecall to run.
In Conclusion:
prefer remotecall to #spawnat, particularly in macros, for sake of being easier to reason about.
Sometimes you have to wait for things before fetching them. That is probably a bug
sometimes waiting for X, when X is to be set by a remotecall (or #spawnat) returning future Y, requires waiting for Y first. Also probably a bug
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.
I am developing a (large) package which does not load properly anymore.
This happened after I changed a single line of code.
When I attempt to load the package (with Needs), the package starts loading and then one of the setdelayed definitions “comes alive” (ie. Is somehow evaluated), gets trapped in an error trapping routine loaded a few lines before and the package loading aborts.
The error trapping routine with abort is doing its job, except that it should not have been called in the first place, during the package loading phase.
The error message reveals that the wrong argument is in fact a pattern expression which I use on the lhs of a setdelayed definition a few lines later.
Something like this:
……Some code lines
Changed line of code
g[x_?NotGoodQ]:=(Message[g::nogood, x];Abort[])
……..some other code lines
g/: cccQ[g[x0_]]:=True
When I attempt to load the package, I get:
g::nogood: Argument x0_ is not good
As you see the passed argument is a pattern and it can only come from the code line above.
I tried to find the reason for this behavior, but I have been unsuccessful so far.
So I decided to use the powerful Workbench debugging tools .
I would like to see step by step (or with breakpoints) what happens when I load the package.
I am not yet too familiar with WB, but it seems that ,using Debug as…, the package is first loaded and then eventually debugged with breakpoints, ect.
My problem is that the package does not even load completely! And any breakpoint set before loading the package does not seem to be effective.
So…2 questions:
can anybody please explain why these code lines "come alive" during package loading? (there are no obvious syntax errors or code fragments left in the package as far as I can see)
can anybody please explain how (if) is possible to examine/debug
package code while being loaded in WB?
Thank you for any help.
Edit
In light of Leonid's answer and using his EvenQ example:
We can avoid using Holdpattern simply by definying upvalues for g BEFORE downvalues for g
notGoodQ[x_] := EvenQ[x];
Clear[g];
g /: cccQ[g[x0_]] := True
g[x_?notGoodQ] := (Message[g::nogood, x]; Abort[])
Now
?g
Global`g
cccQ[g[x0_]]^:=True
g[x_?notGoodQ]:=(Message[g::nogood,x];Abort[])
In[6]:= cccQ[g[1]]
Out[6]= True
while
In[7]:= cccQ[g[2]]
During evaluation of In[7]:= g::nogood: -- Message text not found -- (2)
Out[7]= $Aborted
So...general rule:
When writing a function g, first define upvalues for g, then define downvalues for g, otherwise use Holdpattern
Can you subscribe to this rule?
Leonid says that using Holdpattern might indicate improvable design. Besides the solution indicated above, how could one improve the design of the little code above or, better, in general when dealing with upvalues?
Thank you for your help
Leaving aside the WB (which is not really needed to answer your question) - the problem seems to have a straightforward answer based only on how expressions are evaluated during assignments. Here is an example:
In[1505]:=
notGoodQ[x_]:=True;
Clear[g];
g[x_?notGoodQ]:=(Message[g::nogood,x];Abort[])
In[1509]:= g/:cccQ[g[x0_]]:=True
During evaluation of In[1509]:= g::nogood: -- Message text not found -- (x0_)
Out[1509]= $Aborted
To make it work, I deliberately made a definition for notGoodQ to always return True. Now, why was g[x0_] evaluated during the assignment through TagSetDelayed? The answer is that, while TagSetDelayed (as well as SetDelayed) in an assignment h/:f[h[elem1,...,elemn]]:=... does not apply any rules that f may have, it will evaluate h[elem1,...,elem2], as well as f. Here is an example:
In[1513]:=
ClearAll[h,f];
h[___]:=Print["Evaluated"];
In[1515]:= h/:f[h[1,2]]:=3
During evaluation of In[1515]:= Evaluated
During evaluation of In[1515]:= TagSetDelayed::tagnf: Tag h not found in f[Null]. >>
Out[1515]= $Failed
The fact that TagSetDelayed is HoldAll does not mean that it does not evaluate its arguments - it only means that the arguments arrive to it unevaluated, and whether or not they will be evaluated depends on the semantics of TagSetDelayed (which I briefly described above). The same holds for SetDelayed, so the commonly used statement that it "does not evaluate its arguments" is not literally correct. A more correct statement is that it receives the arguments unevaluated and does evaluate them in a special way - not evaluate the r.h.s, while for l.h.s., evaluate head and elements but not apply rules for the head. To avoid that, you may wrap things in HoldPattern, like this:
Clear[g,notGoodQ];
notGoodQ[x_]:=EvenQ[x];
g[x_?notGoodQ]:=(Message[g::nogood,x];Abort[])
g/:cccQ[HoldPattern[g[x0_]]]:=True;
This goes through. Here is some usage:
In[1527]:= cccQ[g[1]]
Out[1527]= True
In[1528]:= cccQ[g[2]]
During evaluation of In[1528]:= g::nogood: -- Message text not found -- (2)
Out[1528]= $Aborted
Note however that the need for HoldPattern inside your left-hand side when making a definition is often a sign that the expression inside your head may also evaluate during the function call, which may break your code. Here is an example of what I mean:
In[1532]:=
ClearAll[f,h];
f[x_]:=x^2;
f/:h[HoldPattern[f[y_]]]:=y^4;
This code attempts to catch cases like h[f[something]], but it will obviously fail since f[something] will evaluate before the evaluation comes to h:
In[1535]:= h[f[5]]
Out[1535]= h[25]
For me, the need for HoldPattern on the l.h.s. is a sign that I need to reconsider my design.
EDIT
Regarding debugging during loading in WB, one thing you can do (IIRC, can not check right now) is to use good old print statements, the output of which will appear in the WB's console. Personally, I rarely feel a need for debugger for this purpose (debugging package when loading)
EDIT 2
In response to the edit in the question:
Regarding the order of definitions: yes, you can do this, and it solves this particular problem. But, generally, this isn't robust, and I would not consider it a good general method. It is hard to give a definite advice for a case at hand, since it is a bit out of its context, but it seems to me that the use of UpValues here is unjustified. If this is done for error - handling, there are other ways to do it without using UpValues.
Generally, UpValues are used most commonly to overload some function in a safe way, without adding any rule to the function being overloaded. One advice is to avoid associating UpValues with heads which also have DownValues and may evaluate -by doing this you start playing a game with evaluator, and will eventually lose. The safest is to attach UpValues to inert symbols (heads, containers), which often represent a "type" of objects on which you want to overload a given function.
Regarding my comment on the presence of HoldPattern indicating a bad design. There certainly are legitimate uses for HoldPattern, such as this (somewhat artificial) one:
In[25]:=
Clear[ff,a,b,c];
ff[HoldPattern[Plus[x__]]]:={x};
ff[a+b+c]
Out[27]= {a,b,c}
Here it is justified because in many cases Plus remains unevaluated, and is useful in its unevaluated form - since one can deduce that it represents a sum. We need HoldPattern here because of the way Plus is defined on a single argument, and because a pattern happens to be a single argument (even though it describes generally multiple arguments) during the definition. So, we use HoldPattern here to prevent treating the pattern as normal argument, but this is mostly different from the intended use cases for Plus. Whenever this is the case (we are sure that the definition will work all right for intended use cases), HoldPattern is fine. Note b.t.w., that this example is also fragile:
In[28]:= ff[Plus[a]]
Out[28]= ff[a]
The reason why it is still mostly OK is that normally we don't use Plus on a single argument.
But, there is a second group of cases, where the structure of usually supplied arguments is the same as the structure of patterns used for the definition. In this case, pattern evaluation during the assignment indicates that the same evaluation will happen with actual arguments during the function calls. Your usage falls into this category. My comment for a design flaw was for such cases - you can prevent the pattern from evaluating, but you will have to prevent the arguments from evaluating as well, to make this work. And pattern-matching against not completely evaluated expression is fragile. Also, the function should never assume some extra conditions (beyond what it can type-check) for the arguments.
This question is essentially a duplicate of Debugging infinite loops in Haskell programs with GHCi. The author there solved it manually, though I'd like to know other solutions.
(my particular problem)
I have an arrow code which contains a recursive invocation,
testAVFunctor = proc x -> do
y <- errorArrow "good error" -< x
z <- isError -< y
(passError ||| testAVFunctor) -< trace "value of z" z
The errorArrow should make the recursive testAVFunctor not execute, since that will cause isError to return a Left (AVError "good error") which should in turn choose the passError route and bypass the recursive call.
The very odd thing is that inserting "trace" calls at popular sites like the function composition results in the program emitting a finite amount of output, then freezing. Not what I'd expect from an infinite term expansion problem. (see edit 1)
I've uploaded my source code here if anyone is so curious.
EDIT 1
I wasn't looking in the right place (if you care to look at the source, apparently avEither was looping). The way I got there was by compiling a binary, and running gdb:
gdb Main
r (runs code)
Ctrl+C (send interrupt). The backtrace will be useless, but what you can do, is hit
s (step). Then, hold down the enter key; you should see a lot of method names fly by. Hopefully one of them will be recognizable.
You can compile with ghc flag -O0 to disable optimization, which can reveal more method names.
EDIT 3
Apparently, the proc x -> do block above was causing the code to generate combinators, which were calling the AVFunctor.arr lifting method to be called -- something in there must be violating laziness. If I rewrite the top level function as
testAVFunctor = errorArrow "good error" >>>
isError >>> (passError ||| testAVFunctor)
then everything works fine. I guess it's time to try learning and using garrows (by a grad student here at Berkeley).
My general takeaway from the experience is that ghci debugging can be frustrating. For example, I managed to make the argument f of AVFunctor.arr show up as a local variable, but I can't get anything terribly informative from it:
> :i f
f :: b -> c -- <no location info>
Revised source code is here
Keep in mind that the meaning of (|||) depends on the arrow, and testAVFunctor is an infinite object of your arrow:
testAVFunctor = proc x -> do
...
(passError ||| proc x -> do
...
(passError ||| proc x -> ...) -< trace "value of z" z)
-< trace "value of z" z
I'm not sure if you were aware of that. Examine the definition of (|||) (or if there isn't one, left) to see if it can handle infinite terms. Also check (>>>) (er, (.) in modern versions I think). Make sure the combinators are not strict, because then an infinite term will diverge. This may involve making patterns lazier with ~ (I have had to do this a lot when working with arrows). The behavior you're seeing might be caused by too much strictness in one of the combinators, so it evaluates "far enough" to give some output but then gets stuck later.
Good luck. You're into the deep subtleness of Haskell.
When debugging a function I usually use
library(debug)
mtrace(FunctionName)
FunctionName(...)
And that works quite well for me.
However, sometimes I am trying to debug a complex function that I don't know. In which case, I can find that inside that function there is another function that I would like to "go into" ("debug") - so to better understand how the entire process works.
So one way of doing it would be to do:
library(debug)
mtrace(FunctionName)
FunctionName(...)
# when finding a function I want to debug inside the function, run again:
mtrace(FunctionName.SubFunction)
The question is - is there a better/smarter way to do interactive debugging (as I have described) that I might be missing?
p.s: I am aware that there where various questions asked on the subject on SO (see here). Yet I wasn't able to come across a similar question/solution to what I asked here.
Not entirely sure about the use case, but when you encounter a problem, you can call the function traceback(). That will show the path of your function call through the stack until it hit its problem. You could, if you were inclined to work your way down from the top, call debug on each of the functions given in the list before making your function call. Then you would be walking through the entire process from the beginning.
Here's an example of how you could do this in a more systematic way, by creating a function to step through it:
walk.through <- function() {
tb <- unlist(.Traceback)
if(is.null(tb)) stop("no traceback to use for debugging")
assign("debug.fun.list", matrix(unlist(strsplit(tb, "\\(")), nrow=2)[1,], envir=.GlobalEnv)
lapply(debug.fun.list, function(x) debug(get(x)))
print(paste("Now debugging functions:", paste(debug.fun.list, collapse=",")))
}
unwalk.through <- function() {
lapply(debug.fun.list, function(x) undebug(get(as.character(x))))
print(paste("Now undebugging functions:", paste(debug.fun.list, collapse=",")))
rm(list="debug.fun.list", envir=.GlobalEnv)
}
Here's a dummy example of using it:
foo <- function(x) { print(1); bar(2) }
bar <- function(x) { x + a.variable.which.does.not.exist }
foo(2)
# now step through the functions
walk.through()
foo(2)
# undebug those functions again...
unwalk.through()
foo(2)
IMO, that doesn't seem like the most sensible thing to do. It makes more sense to simply go into the function where the problem occurs (i.e. at the lowest level) and work your way backwards.
I've already outlined the logic behind this basic routine in "favorite debugging trick".
I like options(error=recover) as detailed previously on SO. Things then stop at the point of error and one can inspect.
(I'm the author of the 'debug' package where 'mtrace' lives)
If the definition of 'SubFunction' lives outside 'MyFunction', then you can just mtrace 'SubFunction' and don't need to mtrace 'MyFunction'. And functions run faster if they're not 'mtrace'd, so it's good to mtrace only as little as you need to. (But you probably know those things already!)
If 'MyFunction' is only defined inside 'SubFunction', one trick that might help is to use a conditional breakpoint in 'MyFunction'. You'll need to 'mtrace( MyFunction)', then run it, and when the debugging window appears, find out what line 'MyFunction' is defined in. Say it's line 17. Then the following should work:
D(n)> bp( 1, F) # don't bother showing the window for MyFunction again
D(n)> bp( 18, { mtrace( SubFunction); FALSE})
D(n)> go()
It should be clear what this does (or it will be if you try it).
The only downsides are: the need to do it again whenever you change the code of 'MyFunction', and; the slowing-down that might occur through 'MyFunction' itself being mtraced.
You could also experiment with adding a 'debug.sub' argument to 'MyFunction', that defaults to FALSE. In the code of 'MyFunction', then add this line immediately after the definition of 'SubFunction':
if( debug.sub) mtrace( SubFunction)
That avoids any need to mtrace 'MyFunction' itself, but does require you to be able to change its code.