什么是有效的方法来调试R中加载的Rcpp编译代码(在OS X Mavericks上)?

时间:2014-01-20 04:38:47

标签: r debugging osx-mavericks rstudio rcpp

调试加载到R中的共享对象的最有效和最快捷的方法是什么,特别是在OS X Mavericks上?我主要对调试编译的Rcpp代码感兴趣。

我已经阅读了有关使用gdb的调试编译代码(http://cran.r-project.org/doc/manuals/R-exts.html#Debugging-compiled-code)的R外部代码,但是Mavericks并未正式支持gdb。但是,似乎lldb是一个可行的替代方案吗?我找到了最有用的资源,用于研究如何从Dirk对这篇文章的回复中调试R中的编译代码(感谢Dirk!)(Debugging (line by line) of Rcpp-generated DLL under Windows)。

我可以按照下面逐步明确说明的步骤成功调试已编译的Rcpp代码,其他Rcpp新手可能会觉得这很有用(为长度道歉,但我认为最好是明确而不是省略并且是模糊)。但是这个开发过程有点乏味且耗时。

问题:

  1. 与我在下面的操作相比,是否有更快速和/或更简单的方法来调试已编译的Rcpp代码?

  2. 我是Rstudio的忠实粉丝,并希望合并从该IDE创建的调试共享对象,所以如果有人知道如何做到这一点,我会有兴趣知道吗? Rstudio似乎使用属性,看起来下面的步骤4需要修改,因为编译后在临时目录中似乎没有.cpp文件(在我的示例中,没有“file5156292c0b48.cpp”文件)

  3. 步骤:

    1)(一次关闭)转到目录〜/ .R(带有。的隐藏目录)。创建一个名为“Makevars”的新文件,并在其中添加行CXXFLAGS=-g -O0 -Wall

    2)在终端中,键入R -d lldb以启动R. lldb现在将启动。

    3)在lldb命令行输入run。这将启动R.

    4)编译Rcpp代码并找到编译对象的位置。德克对上述帖子的回应显示了一种方法。这是我将在这里使用的一个例子。在R中运行以下命令:

    library(inline)
    
    fun <- cxxfunction(signature(), plugin="Rcpp", verbose=TRUE, body='
    int theAnswer = 1;
    int theAnswer2 = 2;
    int theAnswer3 = 3;
    double theAnswer4 = 4.5;
    return wrap(theAnswer4);
    ')
    

    这会创建一个编译的共享对象和其他文件,可以通过在R中运行setwd(tempdir())和list.files()找到。会有一个.cpp文件,比如“file5156292c0b48.cpp”和.so文件如“file5156292c0b48.so”

    5)通过在R命令行运行dyn.load("file5156292c0b48.so")将共享对象加载到R中

    6)现在我们要在这个.so对象中调试C ++代码。点击ctrl + c返回lldb。现在我想在file5156292c0b48.cpp文件中的特定行设置一个断点。我通过打开另一个终端并查看file5156292c0b48.cpp中感兴趣的行号来找到正确的行号。假设它是第31行,它对应于theAnswer = 1中的行;以上在我的例子中。然后我在lldb命令行输入:breakpoint set -f file5156292c0b48.cpp -l 31。调试器打印出已经设置了断点和其他一些东西...

    7)通过在lldb中运行cont返回R(在我按下Enter键之前,R提示不会自动出现)并调用该函数。在R命令行运行fun()。现在我正在调试共享对象(点击n转到下一行,p [对象名]打印变量等)....

2 个答案:

答案 0 :(得分:10)

要调试这样的简单Rcpp脚本,你可以做的一件事就是创建一个嵌入了R的.cpp应用程序(带有一个main)。这样你可以直接使用Xcode调试它,这将为你提供一个很好的调试经验。

当您开始想要调试包时,它会变得更加复杂。

答案 1 :(得分:2)

这很难。我尝试使用独立的C ++应用程序来运行Xcode和Eclipse,但是很难让所有的头文件和库工作。此外,RcppExport代码通过一个似乎真正混淆Xcode的指针调用你的真实R函数,我无法进入我的函数。

我最终得到了(gdb或lldb): 在R: R -d lldb 在调试器中,设置断点: b functionName run 在R: .Call(etc) # or just call your R code which invokes compiled C/C++ code 然后在调试器中一旦发生中断,你就可以步进,检查帧等等。

这个lldb / gdb command quick reference帮了很多忙。

忘记在此时尝试在GUI中执行此操作。希望Rstudio能够实现这一目标。