已经在R的浏览器中添加跟踪/断点

r2e*_*ans 11 debugging trace r

某些调试器允许您在调试器中动态添加断点.R中的功能是否可行?一个例子:

quux <- function(..)
{ # line 1
  "line 2"
  "line 3"
  "line 4"
  "line 5"
  "line 6"
}

trace("quux", tracer = browser, at = 3)
# [1] "quux"
quux()
# Tracing quux() step 3 
# Called from: eval(expr, envir, enclos)
# Browse[1]> 
# debug: [1] "line 3"
Run Code Online (Sandbox Code Playgroud)

在调试时,我相信我想在代码中超前.想象一下这个函数有几百行代码,我宁愿不介绍它们.

我希望能够做到这一点,并从当前行跳到下一个有趣的行,但不幸的是它只是继续执行该功能.

# Browse[2]>
trace("quux", tracer = browser, at = 5)
# [1] "quux"
# Browse[2]>
c    
# [1] "line 6"
# # (out of the debugger)
Run Code Online (Sandbox Code Playgroud)

trace在调试器中的调用只是将断点添加到原始(全局)函数,如图所示,如果我立即再次调用该函数:

quux()
# Tracing quux() step 5 
# Called from: eval(expr, envir, enclos)
# Browse[1]> 
# debug: [1] "line 5"
Run Code Online (Sandbox Code Playgroud)

我尝试at=c(3,5)在浏览器中同时设置两个(但是这只是设置这些行,当我退出调试器并再次调用该函数时).

我猜这与trace附加断点的函数有关.调查trace(和.TraceWithMethods),我认为我需要设置where,但我无法弄清楚如何让它在调试中函数设置新的断点/跟踪.

(更大的图片是我正在对一个处理kafka引导的数据流的函数进行故障排除.我的两个选项目前是(a)用更合适的跟踪重启函数,但这需要我清除并重新启动数据流;或者(b)在调试器中逐行进行,当有数百行代码时很乏味.)

Ben*_*sen 2

这可能是一种解决方案。首先按照您的帖子中的操作:

> quux <- function(..)
+ { # line 1
+   x <- 1   # added for illustration
+   "line 3"
+   "line 4"
+   "line 5"
+   print(x) # added for illustration
+   "line 7"
+   "line 8"
+ }
> 
> trace("quux", tracer = browser, at = 4)
[1] "quux"
> quux()
Tracing quux() step 4 
Called from: eval(expr, p)
Browse[1]> n
debug: [1] "line 4"
Run Code Online (Sandbox Code Playgroud)

接下来,我们在调试器中进行如下操作:

Browse[2]> this_func <- eval(match.call()[[1]])       # find out which funcion is called
Browse[2]> formals(this_func) <- list()               # remove arguments
Browse[2]> body(this_func) <- body(this_func)[-(2:4)] # remove lines we have evalutaed   
Browse[2]> trace("this_func", tracer = browser, 
+                at = 8 - 4 + 1)                      # at new line - old trace point
Tracing function "this_func" in package "base"
[1] "this_func"
Browse[2]> this_func                                  # print for illustration
function () 
{
    "line 5"
    print(x)
    "line 7"
    "line 8"
}
Browse[2]> environment(this_func) <- environment()    # change enviroment so x is present
Browse[2]> this_func()                                # call this_func
[1] 1
[1] "line 8"
Run Code Online (Sandbox Code Playgroud)

缺点是,"line 5"在退出对 的调用quux后,我们会回到原来的对 的调用this_func。此外,我们必须跟踪最后一个at值。我们可以从另一个函数中得到这个吗?