R:如何使dump.frames()包含所有变量,以便以后使用debugger()进行事后调试



我有下面的代码,它引发了一个错误,并写了一个使用dump.frames()的所有帧的转储,如由Hadley Wickham提出的:

a <- -1
b <- "Hello world!"
bad.function <- function(value)
{
  log(value)                  # the log function may cause an error or warning depending on the value
}
tryCatch( {
             a.local.value <- 42
             bad.function(a)
             bad.function(b)
          },
          error = function(e)
          {
            dump.frames(to.file = TRUE)
          })

当我重新启动R会话并加载转储以通过

调试问题时
load(file = "last.dump.rda")
debugger(last.dump)

我找不到我的变量(a, b, a.local.value),也找不到我的函数"bad"。

这使得垃圾场对我来说几乎一文不值。

我必须做些什么才能看到我所有的变量和函数进行体面的事后分析?

debugger的输出为:

> load(file = "last.dump.rda")
> debugger(last.dump)
Message:  non-numeric argument to mathematical functionAvailable environments had calls:
1: tryCatch({
    a.local.value <- 42
    bad.function(a)
    bad.function(b)
2: tryCatchList(expr, classes, parentenv, handlers)
3: tryCatchOne(expr, names, parentenv, handlers[[1]])
4: value[[3]](cond)
Enter an environment number, or 0 to exit  
Selection: 

PS:我使用R3.3.2与RStudio调试

2016年11月20日更新: 请注意,这是不是一个R错误(参见Martin Maechler的回答)。我没有因为可重复性而改变我的答案。上述方法仍然适用。

<标题> 总结

我认为dump.frames(to.file = TRUE)是目前一个反模式(或可能是一个错误)在R中,如果你想在一个新的R会话中调试批处理作业的错误。

你最好把它换成

  dump.frames()
  save.image(file = "last.dump.rda")

options(error = quote({dump.frames(); save.image(file = "last.dump.rda")}))

代替

options(error = dump.frames)

因为全局环境(.GlobalEnv =您通常创建对象的用户工作区)包含在转储中,而当您直接通过dump.frames(to.file = TRUE)保存转储时,它是缺失的。

<标题> 影响分析

如果没有.GlobalEnv,您将丢失重要的顶级对象(及其当前值;-),以了解导致错误的代码行为!

特别是在"非交互式"R批处理作业中出现错误的情况下,如果没有.GlobalEnv,您将丢失,因为您只能在新启动的(空的)交互式工作空间中进行调试,然后您只能访问调用堆栈帧中的对象。

使用上面的代码片段,您可以像往常一样在新的R工作区中检查导致错误的对象值:

load(file = "last.dump.rda")
debugger(last.dump)
<标题> 的背景

dump.frames的实现在工作空间中创建了一个变量last.dump,并用调用堆栈的环境(sys.frames())填充它。每个环境都包含被调用函数的"局部变量")。然后使用save()将该变量保存到一个文件中。

帧栈(调用栈)随着函数的每次调用而增长,参见?sys.frames:

。在帧列表中,GlobalEnv的编号为0。每个后续的函数求值使帧栈增加1,[…]环境,由[…]返回[sys.frame] .

观察.GlobalEnv的索引号为0。

如果我现在开始调试问题中的代码产生的转储,并选择帧1(不是0!)我可以看到变量parentenv指向(引用).GlobalEnv:

Browse[1]> environmentName(parentenv)
[1] "R_GlobalEnv"

因此我认为sys.frames不包含.GlobalEnv,因此也不包含dump.frames(to.file = TRUE),因为它只存储sys.frames而没有.GlobalEnv的所有其他对象。

也许我错了,但这看起来像一个不想要的效果,甚至是一个错误。欢迎讨论!

<标题>引用https://cran.r-project.org/doc/manuals/R-exts.pdf

摘自4.2调试R代码(第96页):

因为去年。dump可以稍后查看,甚至可以在另一个R会话中查看,即使是批量使用r,也可以进行事后调试需要安排转储文件的保存:也可以这样做使用命令行标志——save在运行结束时保存工作空间,或通过

等设置保存工作空间

options(error = quote({dump.frames(to.file=TRUE);问()}))

请注意,与 R Core团队一起工作通常会更有效率,而不是仅仅告诉R有bug。在这里,它显然没有bug,因为它的行为完全符合文档。

如果您以交互方式工作,也没有问题,因为您可以完全访问那里的工作区(可能是LARGE),因此问题仅适用于批处理作业(如您所提到的)。

我们宁愿在这里有一个缺失的功能和功能请求(和bug报告!)应该发生在R bug网站(又名_'R bugzilla'), https://bugs.r-project.org/…然而,通常在阅读了R网站上的相应页面后:https://www.r-project.org/bugs.html.

注意R bugzilla是可搜索的,在目前的情况下,你很快就会发现Andreas Kersting提出了一个很好的建议(也就是说,作为一个愿望,而不是声称一个bug)。https://bugs.r-project.org/bugzilla/show_bug.cgi?id=17116因此,我已经在8月16日为R添加了缺失的功能。是的,当然,R的开发版本,也就是R-devel。参见R-devel邮件列表上今天的帖子,https://stat.ethz.ch/pipermail/r-devel/2016-November/073378.html

相关内容

最新更新