Backlin
Backlin

Reputation: 14852

Searching for objects in the call stack when using the browser

When debugging functions calling other functions in many levels using the browser, it is often hard to know what level to enter on for inspecting a particular variable. It is cryptic when the functions contain apply, sapply, lapply calls producing intermediate levels. Is there a way to search for a variable by name on all levels of the stack?

Let's say I have the functions below, producing an error in f3. I would assume that when entering on level 5 I should be able to list the contents of any environment above the one I am currently in, using the pos or envir argument in some way, but I can't figure out how. How can I for instance look for v2?

f1 <- function(){
    v1 <- 1
    sapply(1:3, f2)
}
f2 <- function(...){
    v2 <- 2
    f3()
}
f3 <- function(){
    v3 <- 3
    stop("Oh no!")
}
> options(error=recover)
> f1()

Error in f3() : Oh no!

Enter a frame number, or 0 to exit

1: f1()
2: #3: sapply(1:3, f2)
3: lapply(X = X, FUN = FUN, ...)
4: FUN(1:3[[1]], ...)
5: #3: f3()

Upvotes: 5

Views: 183

Answers (1)

Matthew Plourde
Matthew Plourde

Reputation: 44614

You obtain the callstack in a list with sys.frames. In this case, if you call sys.frames after the browser starts, you'll get a list of length 9. Frames 6-9 include the call that raised the error and the calls involved in starting the browser (you can see this by calling sys.calls). The first five frames are the ones displayed in the call stack that recover prints. Once the browser starts, you can look at the namespace of each level of the callstack in your example with

lapply(sys.frames()[1:5], ls)

or search for the frame containing the variable with

which(sapply(sys.frames(), function(frame) 'v2' %in% ls(frame)))

Upvotes: 5

Related Questions