Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

undebug all functions

Tags:

r

debugging

Consider we have called debug() for several functions to make a breakpoint on them. When we find and solve the bug, is there anyway to undebug() all functions already marked by debug() by a single command?

Here is a good benchmark to see if your proposed method really works perfectly:

> library(limma) # bioconductor > debug(read.ilmn) > read.ilmn("a.txt") # No problem if this file does not exist Browse[2]> debug(.read.oneilmnfile) # This is the debug browser for read.ilmn() Browse[2]> Q # To exit debug browser > undebug.all() # Here run your proposed function to undebug everything! > read.ilmn("a.txt") # Now if the debug browser is not started, you are lucky to pass this test! 

You may see the accepted answer below. Any case for which this answer does not work, or cleaner versions, are more than welcome.

like image 582
Ali Avatar asked Oct 09 '12 19:10

Ali


People also ask

How do you debug a specific function?

To debug a function which is defined inside another function, single-step through to the end of its definition, and then call debug on its name. If you want to debug a function not starting at the very beginning, use trace(..., at = *) or setBreakpoint .

How do I turn off debug mode in r?

c to leave the debug mode and continue with the regular execution of the function. Q to stop debug mode, terminate the function, and return to the R prompt.


2 Answers

This was my solution ...

edit: revised to deal with finding objects in namespaces. The code is already getting a little bit crufty, since I don't really understand the methods for manipulating/querying namespaces all that well, and since I was working by trial and error. Cleaner versions would be welcome. There are almost certainly other corner cases that will fail.

## return the names of the objects (from a vector of list of ## names of objects) that are functions and have debug flag set isdebugged_safe <- function(x,ns=NULL)  {     g <- if (is.null(ns)) get(x) else getFromNamespace(x,ns)     is.function(g) && isdebugged(g) }  which_debugged <- function(objnames,ns=NULL) {     if (!length(objnames)) return(character(0))     objnames[sapply(objnames,isdebugged_safe,ns=ns)] }  all_debugged <- function(where=search(), show_empty=FALSE) {     ss <- setNames(lapply(where,function(x) {         which_debugged(ls(x,all.names=TRUE))         }),gsub("package:","",where))     ## find attached namespaces     ## (is there a better way to test whether a      ##    namespace exists with a given name??)     ns <- unlist(sapply(gsub("package:","",where),                  function(x) {                      if (inherits({n <- try(getNamespace(x),silent=TRUE)},                          "try-error")) NULL else x                  }))     ss_ns <- setNames(lapply(ns,function(x) {         objects <- ls(getNamespace(x),all.names=TRUE)         which_debugged(objects,ns=x)         }),ns)     if (!show_empty) {         ss <- ss[sapply(ss,length)>0]         ss_ns <- ss_ns[sapply(ss_ns,length)>0]     }     ## drop overlaps     for (i in names(ss))         ss_ns[[i]] <- setdiff(ss_ns[[i]],ss[[i]])     list(env=ss,ns=ss_ns) }  undebug_all <- function(where=search()) {     aa <- all_debugged(where)     lapply(aa$env,undebug)     ## now debug namespaces     invisible(mapply(function(ns,fun) {         undebug(getFromNamespace(fun,ns))     },names(aa$ns),aa$ns)) } 

The code is also posted at http://www.math.mcmaster.ca/bolker/R/misc/undebug_all.R

Example:

library(nlme) debug(lme) ## define functions source(url("http://www.math.mcmaster.ca/bolker/R/misc/undebug_all.R")) undebug_all() fm1 <- lme(distance ~ age, data = Orthodont) # from ?lme 

In this case lme runs without entering the debugger.

Another, harder example:

library(limma) source(url("http://www.math.mcmaster.ca/bolker/R/misc/undebug_all.R")) debug(read.ilmn) debug(limma:::.read.oneilmnfile) all_debugged() undebug_all() read.ilmn() read.ilmn("a.txt") 

Note that read.ilmn() and read.ilmn("a.txt") appear to behave differently from a debugging standpoint (I don't understand why ...)

like image 112
Ben Bolker Avatar answered Sep 22 '22 16:09

Ben Bolker


No, there is no completely reliable way to undebug() all functions. (I only say this because I've seen it discussed several times on R-devel and R-help.)

In this discussion, Brian Ripley weighed in, noting that:

Debugging is a property of a function object (a bit in the sxpinfo) and so you would have to traverse all reachable objects (as gc does) to find them all.

Here's a snippet in which Robert Gentleman answers (in the negative) a question about whether "there is a convenient way to know at any time which are the function flagged with debug() or trace() in a R session":

You probably didn't get an answer because the answer is no, there is no easy way.

like image 20
Josh O'Brien Avatar answered Sep 25 '22 16:09

Josh O'Brien