Post-mortem debugging in R

When a function quits because of an error, there is information available to help in debugging. This page gives a quick introduction; for more detail see Roger Peng's "An Introduction to the Interactive Debugging Tools in R". See also the description of R's exception handling mechanisms.

Using traceback()
Using options(error=recover)
Converting warnings to errors

Using traceback()

The traceback() function shows the call stack at the time of the last unhandled error. For example, the error message printed when incompatible arguments are passed to the lm() function is actually generated in the model.frame.default function:

> lm(y ~ x)
Error in model.frame(formula, rownames, variables, varnames, extras, extranames,  :
        variable lengths differ
> traceback()
5: model.frame.default(formula = y ~ x, drop.unused.levels = TRUE)
4: model.frame(formula = y ~ x, drop.unused.levels = TRUE)
3: eval(expr, envir, enclos)
2: eval(mf, parent.frame())
1: lm(y ~ x)

An alternative approach to post-mortem debugging is to use the recover() function. Recover can be set as the error-handling function in at least two ways, using options(error=) and using withCallingHandlers().

Using options(error=recover)

If you execute options(error=recover), any error will cause a break to recover(), which presents you with a traceback() list of frames that were active at the time of the error. The recover() function then allows you to examine the variables in any of the saved frames, using the usual browser(): but the execution commands (n, etc.) are not functional. For example,

> options(error=recover)
> lm(y ~ x)
Error in model.frame(formula, rownames, variables, varnames, extras, extranames,  :
        variable lengths differ

Enter a frame number, or 0 to exit
1:lm(y ~ x)
2:eval(mf, parent.frame())
3:eval(expr, envir, enclos)
4:model.frame(formula = y ~ x, drop.unused.levels = TRUE)
5:model.frame.default(formula = y ~ x, drop.unused.levels = TRUE)
Selection: 1
Called from: eval(expr, envir, enclos)
Browse[1]> x
[1] FALSE
Browse[1]> formula
y ~ x
Browse[1]> mf
model.frame(formula = y ~ x, drop.unused.levels = TRUE)
Browse[1]>

Enter a frame number, or 0 to exit
1:lm(y ~ x)
2:eval(mf, parent.frame())
3:eval(expr, envir, enclos)
4:model.frame(formula = y ~ x, drop.unused.levels = TRUE)
5:model.frame.default(formula = y ~ x, drop.unused.levels = TRUE)
Selection: 0

Converting warnings to errors

Normally R doesn't print warnings at the time they are issued, it collects them and prints them all when execution is complete. Executing options(warn=1) causes R to print warnings as they occur, and executing options(warn=2) converts them to errors, which will usually abort execution and allow post-mortem debugging.

Last modified: Fri 11 Nov 2005, by Duncan Murdoch