如何在 R 中无错误地显示堆栈跟踪?

How to show stack trace without error in R?

在 JavaScript 中,我可以使用 console.log(new Error().stack)console.trace() 来显示堆栈跟踪。

R 中有这样的东西吗?我可以在我的位置显示调用堆栈跟踪的函数吗?我有复杂的应用程序,很难在调用的地方跟踪代码,在调用函数的地方显示堆栈跟踪将简化查找代码执行方式的过程。

我试过这个技巧:

foo <- function() bar()
bar <- function() {
  tryCatch(
    stop('NOP'),
    error = function(e) {
      print(traceback(e))
  })
}
foo()

但它不起作用我需要在顶层捕获错误才能看到该堆栈。有没有简单的函数可以在调用时显示堆栈帧?

编辑: 这是在 JavaScript 中的示例,这是我希望它如何工作的示例,在 R 中可能有类似的事情吗?

function foo() {
  bar();
}
function bar() {
  baz();
}
function baz() {
  // console.trace is dev tools function
  // this will show up the stack if open dev tools and then run the snippet
  console.trace();
  console.log(new Error().stack);
}
foo();

如您所见,并没有抛出错误,它只是创建了一个对象,浏览器会将调用的堆栈跟踪添加到该对象,因此可以对其进行检查。

如果你想在不抛出错误的情况下查看调用堆栈,你可以尝试这样的操作:

show_stack <- function() {
  cat("#----- Stack containing call to show_stack -----#\n\n")
  x <- sys.calls()
  lapply(head(x, -1), function(x) {print(x); cat("\n")})
  cat("#-----------------------------------------------#\n\n")
}

您只需在要跟踪的函数中插入:

foo <- function() bar()
bar <- function() baz()
baz <- function() show_stack()

导致:

foo()
#> #----- Stack containing call to show_stack -----#
#> 
#> foo()
#> 
#> function() bar()
#> 
#> function() baz()
#> 
#> #-----------------------------------------------#

或者,再举一个 real-world 的例子:

my_mean <- function(x) {
  show_stack()
  sum(x)/length(x)
}

在一次通话中可能 运行 多次:

tapply(iris$Sepal.Length, iris$Species, my_mean)
#> #----- Stack containing call to show_stack -----#
#> 
#> tapply(iris$Sepal.Length, iris$Species, my_mean)
#> 
#> lapply(X = ans[index], FUN = FUN, ...)
#> 
#> FUN(X[[i]], ...)
#> 
#> #-----------------------------------------------#
#> 
#> #----- Stack containing call to show_stack -----#
#> 
#> tapply(iris$Sepal.Length, iris$Species, my_mean)
#> 
#> lapply(X = ans[index], FUN = FUN, ...)
#> 
#> FUN(X[[i]], ...)
#> 
#> #-----------------------------------------------#
#> 
#> #----- Stack containing call to show_stack -----#
#> 
#> tapply(iris$Sepal.Length, iris$Species, my_mean)
#> 
#> lapply(X = ans[index], FUN = FUN, ...)
#> 
#> FUN(X[[i]], ...)
#> 
#> #-----------------------------------------------#
#> 
#>     setosa versicolor  virginica 
#>      5.006      5.936      6.588