R中功能的"动态/交互式"调试建议?

Tal*_*ili 6 debugging r

调试我经常使用的函数时

library(debug)
mtrace(FunctionName)
FunctionName(...)
Run Code Online (Sandbox Code Playgroud)

这对我很有用.

但是,有时我试图调试一个我不知道的复杂函数.在这种情况下,我可以发现在该函数内部还有另一个我想"进入"("调试")的函数 - 所以为了更好地理解整个过程是如何工作的.

所以这样做的一种方法是:

library(debug)
mtrace(FunctionName)
FunctionName(...)
# when finding a function I want to debug inside the function, run again:
mtrace(FunctionName.SubFunction)
Run Code Online (Sandbox Code Playgroud)

问题是 - 是否有更好/更智能的方式进行交互式调试(正如我所描述的)我可能会丢失?

ps:我知道SO上有关于这个问题的各种问题(见这里).然而,我无法遇到类似的问题/解决方案.

Sha*_*ane 5

不完全确定用例,但遇到问题时,可以调用该函数traceback().这将显示函数调用栈的路径,直到遇到问题为止.如果您倾向于从顶部开始工作,可以debug在进行函数调用之前调用列表中给出的每个函数.然后,您将从头开始学习整个过程.

以下是一个示例,说明如何通过创建一个单步执行的功能,以更系统的方式执行此操作:

walk.through <- function() {
  tb <- unlist(.Traceback)
  if(is.null(tb)) stop("no traceback to use for debugging")
  assign("debug.fun.list", matrix(unlist(strsplit(tb, "\\(")), nrow=2)[1,], envir=.GlobalEnv)
  lapply(debug.fun.list, function(x) debug(get(x)))
  print(paste("Now debugging functions:", paste(debug.fun.list, collapse=",")))
}

unwalk.through <- function() {
  lapply(debug.fun.list, function(x) undebug(get(as.character(x))))
  print(paste("Now undebugging functions:", paste(debug.fun.list, collapse=",")))
  rm(list="debug.fun.list", envir=.GlobalEnv)
}
Run Code Online (Sandbox Code Playgroud)

这是一个使用它的虚拟示例:

foo <- function(x) { print(1); bar(2) }
bar <- function(x) { x + a.variable.which.does.not.exist }
foo(2)

# now step through the functions
walk.through() 
foo(2)

# undebug those functions again...
unwalk.through()
foo(2)
Run Code Online (Sandbox Code Playgroud)

IMO,这似乎不是最明智的事情.简单地进入问题发生的功能(即最低级别)并向后工作更有意义.

我已经在"最喜欢的调试技巧"中概述了这个基本例程背后的逻辑.


Dir*_*tel 5

我喜欢之前在SO上options(error=recover)详述的内容.事情然后停在错误点,人们可以检查.

  • @Tal:我不知道如何使用mtrace:你必须自己解决这个问题.但是你可以创建自己的自定义错误函数是我的一般观点. (3认同)
  • 我不知道mtrace是如何工作的,但你可以创建自己的错误条件来正确使用它:`options(error = function(x)mtrace(x,...))`. (2认同)