[ESS] ess-tracebug behavior [probably wishlist]

Ross Boylan ross at biostat.ucsf.edu
Sat May 4 20:50:25 CEST 2013

On Saturday, May 04, 2013 03:28:13 AM Vitalie Spinu wrote:
>  >> Ross Boylan <ross at biostat.ucsf.edu>
>  >> on Fri, 03 May 2013 18:38:02 -0700 wrote:
> [...]
>  > I am now using the latest git:
>  > 650a142597a3be857407e180381acf617f333676.
> There have been some (not yet documented) breaking changes in tracebug's
> user interface.
Any I might want to know about, other than the undebug you mentioned below?
>  > C-c C-t d to debug a function.  It was exported from a package, and did
>  > appear on the autocompletion list.
>  > 
>  > I did enter the debugger when I hit it, though no special code display. 
>  > The status area of emacs listed a bunch of keys like (M)-N for next.  I
>  > hit Esc-n and got an error"M-n is undefined".   If I enter the R window
>  > I can debug in the usual R way.  Apparently Esc-N (uppercase) works;
>  > having to hit the shift key for a basic debugging operation is awkward.
> Why Esc? M-S-n should work and is pretty convenient.
To get M-something I use the Esc key; my understanding is that M=Esc for my 
environments (WIndows andLinux, though the stuff I've been reporting here is 
all Windows).  Maybe alt or the windows key would be alternates, with alt 
allowing simultaneous keypresses (Esc must be hit and released before the 
others, or at least that's how I do it).

I don't find hitting 3 keys convenient.  It may be all the obvious single keys 
are taken.  Perhaps you could do something like ediff, that basically puts you 
in a separate control window where the keys have special meanings.  That 
interface has always struck me as being a little odd, but it does solve the 
key shortage problem.
> Debuging is now working as a minor mode which is active only during the
> debug. You can customize ess-debug-minor-mode-map to whatever keys you
> want.
> M-N, M-U, M-C were chosen because they are quite easy to type (unless
> you use Esc) and they don't overlap with any editing or navigation
> commands. Everything else we have considered didn't work so well; this
> is the best solution out there.
>  > I wanted to trace into a function that had not been exported.  C-c C-t d
>  > did have it on the completion list--impressive.
> All visible functions from the current context are available. At top
> level you can also debug non-exported function if you are developing
> the package (aka C-c C-t a).
>  > However, although it told me it had set debugging, I did not actually
>  > get a debugger on it.  I typed n in the debugger prompt and it simply
>  > returned (mice.impute.2lmixed.logit was the inner function I was
>  > trying to debug):
>  > 
>  > debug: type <- c(2, type)
>  > Browse[2]>
>  > debug: if (any(type == 1)) return(mice.impute.2lmixed.logit(y, ry, x,
>  > 
>  >     type))
>  > 
>  > Browse[2]> any(type==1)  # set debug on mice.impute.2lmixed.logit here
>  > [1] TRUE
>  > Browse[2]> n
>  > debug: return(mice.impute.2lmixed.logit(y, ry, x, type))
> I will investigate this. There might be some limitations of debug, but
> from my tests the above scenario should work as expected, unless ... see
> bellow.
>  > After using ess-developer on the package (C-c C-t a mice) the private
>  > function is part of the completion list for C-c C-t d at the top level.
> Ok, so you discovered it by yourself:)
>  > I thought the first time I tried this it did not stop, but when I try
>  > to reproduce it's OK. However, the completion lists the function
>  > twice, once as mice.impute2l.mixed.logit and once as
>  > mice::mice.impute.2lmixed.logit.
> Ok, this explains why you didn't get your debug in the first time. Your
> inner function is also an exported function or you have a copy of it in
> .GlobalEnv.
It's not exported, and I don't know how it would get in the global 
environment.  Could putting a debugger on it from top level create a global 
> This is how namespaces work in R, there are two copies, one in package
> environment (visible in search()) and one in the namespace. Both copies
> are enclosed (environment(foo)) by the namespace. Thus the behavior is
> identical.
> The difference is arising when you debug one of them and not another;
> from global context only the package's function is accessible, from the
> package's context only the namespace copy is accessible. So you must
> take care of these issue.
So these are pointers to different function objects, at least if you change one 
by using debug?
> The worst case happens when you debug a package level function. If you
> call it directly the package version is invoked, but when this function
> is called by another function from the same package, then the namespace
> version is invoked.
It's hard to see how that could cause a  problem since I tried typing 
debugonce and debug within the browser while debugging the outer function.  
Shouldn't that get the same function as the code will call if you then step 
into its invocation?

OTOH, it's possible it did work in those scenarios & I just got confused.  I 
may have scanned the stack trace too quickly; one of the problems when they're 
huge is that they are hard to follow.
> I might be able to handle these issues transparently for the user. Will
> look into it. For time being you have to keep track of it yourself.
Since I'm not sure I understand, that will be difficult :)  It would be great if 
this complexity could be concealed.

Let P be the package version of the function and N the namespace version and F 
be the unadorned function name.  I think you are saying that for an exported 
function when you are at the global environment F=P.  But if you're inside the 
namespace, e.g., running P, then F=N. If you debug P and are in a browser 
while doing that debugging, typing debug(F) gets N.  Finally, interactively 
setting debugging with the ess-developer tools is effectively in the same 
environment as your R session, so C-c C-t d F debugs P if you are at outer 
scope, but N if you are in the debugging browser for P.

And if you do C-c C-t a <pkg>  where <pkg> defines F and the C-c C-l, you end 
up debugging... I'm not sure.

And if you reach into the namespace to grab an unexported F ... not sure.
>  > C-c C-t D did not remove the debugging from the function.  Actually, I'm
>  > not sure the uppercase D is getting through;
> It is now bound to C-c C-t u (aka (u)nflag, or (u)ndebug). I removed C-c
> C-t D by mistake.
>  > when it was echoing I only saw a lower case d, and the status message
>  > is "flagged for debugging" after I select the function.
> Yes, you were calling -flag-for-debug.
> [...]
>  > C-u C-t d does debugonce.
> Good idea. but you meant C-u C-c C-t d. A bit of a  mouthful:)
> BTW, for convenience all dev commands are also available with C- prefix
> (C-c C-t C-d).
That's probably easier ono the fingers/brain.
>  > For the record: options(deparse.max.lines) limits the stack trace (an
>  > R, not ESS, feature). It's only partly effective, limiting the stack
>  > trace but not the function body dump as you enter the browser.
> This is what R doc says:
>      ‘deparse.max.lines’: controls the number of lines used when
>           deparsing in ‘traceback’, ‘browser’, and upon entry to a
>           function whose debugging flag is set.  Initially unset, and
>           only used if set to a positive integer.
> So you say this doesn't work as advertised? I would be a bit reluctant
> to clean the display from ESS, as it opens the possibility to "clean"
> something useful.
I'm not sure that the advertisement includes affecting printing the function 
body, which may be an add-on by the R debugger.  Maybe the R debugger needs to 
respect the option.
> Thanks for the input,
>     Vitalie
Thanks for all your help and your work.

More information about the ESS-help mailing list