Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ask R debugger to not truncate the stack calls

Tags:

r

debugging

I would like to debug the following function but suppose that it is useful to see what the argument of moreajaj equals (suppose not so obvious as in this contrived example) when in the debugger. I could print it in the debugger frame, but it is annoying to do that in every frame for every argument. How can one make it so the full argument calls print in debugger when announcing each frame?

options(error = dump.frames)

#### suppose I do not see the function definitions, only see debugger below
some_function <- function(...) {
  stop('give error')
}

willGiveError <- function() {
  some_function(alongargument = "some long kind of default", anotherlongargument = "more long default something as example", moreajaj = "kdjflksdjf")
}

outerFunction <- function() willGiveError()

outerFunction()

# Error in some_function(alongargument = "some long kind of default", anotherlongargument = "more long default something as example",  : 
#   give error
> debugger()
# Message:  Error in some_function(alongargument = "some long kind of default", anotherlongargument = "more long default something as example",  : 
#   give error
# Available environments had calls:
# 1: outerFunction()
# 2: #1: willGiveError()
# 3: #2: some_function(alongargument = "some long kind of default", another
# 4: #2: stop("give error")
# 
# Enter an environment number, or 0 to exit  Selection: 

As you can see above in the debugger output, it is cut after "another" in frame 2, where I would like to see anotherlongargument = "more long default something as example", moreajaj = "kdjflksdjf")

like image 535
Xu Wang Avatar asked Mar 18 '23 22:03

Xu Wang


2 Answers

The textual representations those calls are getting truncated during the evaluation of dump.frames() by its call to limitedLabels().

A simple solution is to write a similar function that differs only in supplying (a sufficiently large value of) the maxwidth= argument to limitedLabels().

## Identical to dump.frames _except_ for addition of maxwidth=10000 argument
my.dump.frames <- 
function (dumpto = "last.dump", to.file = FALSE) 
{
    calls <- sys.calls()
    last.dump <- sys.frames()
    names(last.dump) <- limitedLabels(calls, maxwidth=10000)  # <-- edited line
    last.dump <- last.dump[-length(last.dump)]
    attr(last.dump, "error.message") <- geterrmessage()
    class(last.dump) <- "dump.frames"
    if (dumpto != "last.dump") 
        assign(dumpto, last.dump)
    if (to.file) 
        save(list = dumpto, file = paste(dumpto, "rda", sep = "."))
    else assign(dumpto, last.dump, envir = .GlobalEnv)
    invisible()
}

Then set it, rather than dump.frames, as the function to be run when an error interrupts R's evaluation.

options(error=my.dump.frames)

With that set, running your supplied code and then entering the debugger gives the results you were hoping for:

debugger()
# Message:  Error in some_function(alongargument = "some long kind of default", anotherlongargument = "more long default something as example",  : 
#   give error
# Available environments had calls:
# 1: outerFunction()
# 2: #1: willGiveError()
# 3: #2: some_function(alongargument = "some long kind of default", anotherlongargument = "more long default something as example", moreajaj = "kdjflksdjf")
# 4: #2: stop("give error")
# 
# Enter an environment number, or 0 to exit  Selection: 
like image 137
Josh O'Brien Avatar answered Mar 28 '23 16:03

Josh O'Brien


You can execute traceback() before debugger():

> traceback()
4: stop("give error") at #2
3: some_function(alongargument = "some long kind of default", anotherlongargument = "more long default something as example", 
       moreajaj = "kdjflksdjf") at #2
2: willGiveError() at #1
1: outerFunction()

Note the dump in last.dump (used by debugger()) is truncated to your terminal's width:

> getOption("width")
[1] 80

So you could also modify that (not sure if it would be convenient though) and regenerate last.dump:

> options(width = 1000)
> outerFunction()
> debugger()
Message:  Error in some_function(alongargument = "some long kind of default", anotherlongargument = "more long default something as example",  : 
  give error
Available environments had calls:
1: outerFunction()
2: #1: willGiveError()
3: #2: some_function(alongargument = "some long kind of default", anotherlongargument = "more long default something as example", moreajaj = "kdjflksdjf")
4: #2: stop("give error")

See how the output has not been truncated this time.

like image 35
Peque Avatar answered Mar 28 '23 14:03

Peque