我有下面的代码,它引发了一个错误,并写了一个使用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