[ESS] debugging, mostly tracebug

Vitalie Spinu spinuvit at gmail.com
Sat Apr 6 12:49:17 CEST 2013

  >> Ross Boylan <ross at biostat.ucsf.edu>
  >> on Fri, 05 Apr 2013 17:46:29 -0700 wrote:


 >> Unfortunately there is a long standing limitation in the ess-tracebug
 >> that doesn't allow debuging from within a debug session. I plan to solve
 >> that in a very near future.
 > Do you mean ess-dbg-flag-for-debugging will not work if run from within the
 > browser?  And does "will not work" mean debugging doesn't get put on, or that it
 > does, but ess-tracebug loses the ability to follow the source
 >> location?

Oups, it actually works fine. The limitation is not as severe as I
thought. C-c C-t d does not accept input that is not in the completion
list, and that is not a biggie. The following will work fine:

   foo <- function(a = 4){
       a <- boo()
   boo <- function(){

Place a breakpoint in foo. Then in the debug session C-c C-t d to flag
"boo" for the debugging. It will work.

 >> > Is the enable/disable breakpoints a half way house, so that one can enable and
 >> > disable on the fly, or does that require rereading the source too?
 >> Yes. Breakpoints are for visually marking the source. C-c C-t d is for
 >> flagging for debugging.
 > I was referring to the ess-bp-toggle-state command.

What you think (at least what I think you think) could be quite easily
implemented actually. Browser accepts a condition (this is how
conditional breakpoints are implemented in tracebug). In principle I can
add a condition to each breakpoint and ess-bp-toggle-state would toggle
that condition in R session.

I think I will do that. Thanks.

 >> Your desire for "imaginary breakpoints" goes against "source is real"
 >> philosophy. Suppose I source a function, modified it in several places
 > you mean modified the source file, 

Of course.

 > or modify the function within R by, e.g., apply debug() or trace() to
 > it, or perhaps just redefining it completely?
 >> and inserted a breakpoint. What do you expect would happen?
 > Since I don't follow the scenario it's hard to comment.  In general the version
 > in the source file and in the R image might be out of sync, but I'm not sure
 > what the relevance is to debugging.

The very direct. In order to allow any meaningful implementation of
"dynamic breakpoints", that is a breakpoint that you can insert during
the debugging session, one needs to keep the two versions in sync. Also
the "run till here" facility would need a perfect sync of the two.

Edebug for instance achieves the above by simply marking the whole
buffer readonly for the whole debug session.

But that is not an ideal option either, because in the time between the
instrumentation of the function and actual call the source could have
been edited.

 >> And I hope you don't propose to source the code in the file each time
 >> the user inserts a breakpoint. Only the user can decide when to source
 >> his or her code.
 > "imaginary breakpoints" is your phrase, not mine.  In most debugging systems the
 > source is real but breakpoints are maintained dynamically during the debugging
 > session, and can be put on or off at will.  I do not think such a facility is
 > absurd, though it may be technically difficult in R.

Not difficult in R. But difficult for visual wrapper like
ess-tracebug. The R facility is there. You can call trace() and indicate
a specific line where you want to stop in a function.  There is also
setBreakpoint what operates in a source level directly.

As I said before, the main question is how you keep the source and
evaluated versions of the function in sync in order to allow visual
access to this facility.

I might actually consider relying on setBreakpoint in the future. Then
inserting a breakpoint would not require sourcing the code at all. That
would solve some of your problems, but not the automatic insertion into
a namespace.


 >> How do you propose it would magically realize that?  And if I really
 >> want them in GlobalEnv?

 > The documents for tracebug do not address namespaces; my hope (not expectation)
 > was that they would be handled automatically.  In this context that would mean
 > detecting that the function being taken in was in a namespace and updating that
 > version of a function.  As you point out, that might not be the desired behavior
 > (also realizing that a function that is not exported is part of a namespace
 > requires looking harder).

It becomes more complicated if you recall that multiple namespaces (or
package environments) can have functions with the same name. The story
is way more complicated for methods. Even for simple exported functions
there are 2 copies of those, one in namespace and one in package

So sorry, reading users minds is out of question.

 >> Ess-developer does a fair amount of magic. It recognizes functions as
 >> being part of namespace and inserts them silently. For all the rest
 >> (regions, paragraphs) it asks the user for the environment to insert
 >> them.

 > Hmm, are you saying that it was unnecessary to specify a default
 > namespace for ess-developer?

No, you need to add your packages to the list. There could be many of
them, and you can customize the list to make it persistent.

What I said is that if the function is found in a developed namespace
then it is inserted there without further ado. If you evaluate a region
then you will see a prompt. You better try it yourself.


 > As Kasper pointed out, debugonce deals with the problem of permance, but I think
 > the others remain, including the fact that you have to say debug or debugonce to
 > step into a function, as opposed to issuing, say, a step command.  To clarify,
 > when I say "can't step n steps forward" I mean all at once.  

This is the editors task. Let's not mix it with R. I have this long in
my todo list. Stepping into next call frame is on todo as well.

 >  A related function is to be a able to click on a source line and
 > say "run to there".  That's particularly handy if there's a big loop
 > in between where you are and where you want to go.

Addressed above.

 > Some debuggers allow you to change the flow of execution, e.g., reposition the
 > next step to execute or edit variables.  But those are relatively advanced
 > features.  I believe that changes made while in the browser are not seen by the
 > program when it continues, though I might be wrong.

You can freely edit variables. Local changes in variable bindings are
there for the rest of execution of the body.

What is probably in the back of your mind is that you edit the source
during the debug process and the new version to take over the old
one. This is also possible with the condition that you reevaluate and
insert the new version in correct environment (not the top one).

Trace() does precisely that. You can pass the edit argument to it, and
if your emacsclient is configured correctly then you should see a new
buffer popping up. Once edited and closed, the new function is inserted
in the correct environment. The main problem is that you will not be
able to visually step through anymore because the source reference
starts looking like <tmp>#6.


More information about the ESS-help mailing list