In this post we will talk about native debugging support in R. Mostly, you start debugging when something goes wrong, which have many indications:
- message A generic notification/diagnostic message produced by the message function; execution of the function continues.
- warning An indication that something is wrong but not necessarily fatal; execution of the function continues; generated by the warning function; you got it after the function completion.
- error An indication that a fatal problem has occurred; execution stops; produced by the stop function.
- condition A generic concept for indicating that something unexpected can occur; programmers can create their own conditions.
The primary tools for debugging functions in R are:
traceback() prints out the function call stack after an error occurs; does nothing if there’s no error.
debug(f) flags a function for “debug” mode by setting a breakpoint at the beginning of the function f which allows you to step through execution of a function one line at a time. Use undebug() to turn off debug mode for that function. The debug mode turned off automatically when reloading your code using source().
When you execute your code and hit a breakpoint, you enter the debugger which called the browser in R. The command prompt will be something like Browse[2] instead of just >.
Then you can invoke various debugging operations operations:
- n or Enter to step through single line of code. If it is a line-level breakpoint, you have to hit n the first time, then Enter after that.
- c to skip to the end of the current context (a loop or a function).
- where to get a stack report
- Q to exit the debugger and return to the > command line.
- All normal R operations and functions are still available to you. So for instance to query the value of
a variable, just type its name, as you would in ordinary interactive usage of R. If the variable’s name
is one of the debug() commands, though, say c, you’ll need to do something like print(c) to print it
out.
browser() suspends the execution of a function wherever it is called and puts the function in debug mode.
recover allows you to modify the error behavior so that you can browse the function call stack. It’s a global option that applies for the current global environment. You set it by calling options(error = recover) after that, any functions causes an error to occur you will get function call stack (like the one you got from traceback) with the option to jump into debugging any function that call stack.
trace() allows you to insert debugging code into a function at specific places. For example trace(f, t) would instruct R to call the function t() every time we enter the function f(). This helps if you want to put a breakpoint in the beginning of a specific function in your code file without opening the file, modifying the function, reloading the file using source(). You can just call trace(Your_Function, browser) . When you done with debugging this function you can call, untrace(Your_Function) to remove that debugging feature from your function.
These are interactive tools specifically designed to allow you to pick through a function. There’s also the more blunt technique of inserting print/cat statements in the function.
Stay tuned for more R notes.