traceback()用于交互式和非交互式R会话

Yih*_*Xie 28 r traceback

我观察到了一个traceback()我不理解的交互式和非交互式R会话之间的不同.对于下面的代码,它会产生错误,但在交互式R会话中,我可以看到回溯信息,而如果我将代码保存到test.R并通过Rscript test.R或调用它R -f test.R,我将无法再看到回溯:

f = function() {
  on.exit(traceback())
  1 + 'a'
}
f()
Run Code Online (Sandbox Code Playgroud)

在交互式R会话中:

> f = function() {
+   on.exit(traceback())
+   1 + 'a'
+ }
> f()
Error in 1 + "a" : non-numeric argument to binary operator
1: f()
Run Code Online (Sandbox Code Playgroud)

非交互式执行:

$ Rscript test.R 
Error in 1 + "a" : non-numeric argument to binary operator
Calls: f
No traceback available 
Execution halted
Run Code Online (Sandbox Code Playgroud)

我没有看到解释?traceback,我想知道是否有一种方法可以为非交互式R会话启用回溯.谢谢!

Ben*_*nes 26

使用其参数的默认值,traceback()将查找在调用堆栈.Tracebackbaseenv()for信息中指定的对象.它看起来(from src/main/errors.c)like .Traceback仅在其他条件下R_Interactive || haveHandler建议在非交互式会话期间不创建此对象时才创建.如果没有指定对象.Traceback,您将收到消息"No traceback available".

但是,通过将非NULL值传递给x参数traceback(),可以从非交互式会话中获取有关调用堆栈的信息.使用非零整数值(表示在堆栈中跳过的调用数),调用c级函数(R_GetTraceback)来调查调用堆栈而不是查找.Traceback.

因此,有几种方法可以在非交互式会话中获取回溯信息:

f = function() {
  on.exit(traceback(1))
  1 + 'a'
}
f()
Run Code Online (Sandbox Code Playgroud)

或者,设置options为Brandon Bertelsen建议

options(error=function()traceback(2))
Run Code Online (Sandbox Code Playgroud)

x在两个示例中传递的不同值说明了要跳过的不同数量的函数

  1. on.exit示例中,traceback(1)跳过调用traceback().

  2. 在示例设置中options,有一个额外的匿名函数可以调用traceback()哪些应该/也可以跳过.

在OP中的示例中,traceback()与非交互式会话中的错误情况下提供的自动回溯相比,使用的信息并不多.但是,对于采用(并传递)参数的函数,使用traceback()将比非交互式会话中的调用堆栈的标准表示更具信息性.

  • 请注意,即使发生错误,使用`options(error = function()traceback(2))`也会导致脚本成功退出!一个解决方案是使用`error = function(){traceback(2); if(!interactive())quit("no",status = 1,runLast = FALSE)}`(这里使用的停止参数来自[默认错误行为](https://stat.ethz.ch/R -manual/R-devel的/库/碱/ HTML/stop.html)). (5认同)

pet*_*ner 5

还可以转储调试信息并稍后加载它们。(请参阅?debugger有关该主题的良好帮助页面和评论)

通过例如:

options(error = quote(dump.frames("testdump", TRUE)))
Run Code Online (Sandbox Code Playgroud)

...

load("testdump.rda")
debugger(testdump)
Run Code Online (Sandbox Code Playgroud)

或者

options(error = quote({dump.frames(to.file = TRUE); q(status = 1)}))
Run Code Online (Sandbox Code Playgroud)