如何在Emacs中使用GDB调试带有C代码的R包?

17

我目前正在编写一个R包,并使用Rcpp包中的编译C++代码(对于像我这样的非程序员,Rcpp使得R和C ++代码的交互更加容易,个人认为)。

我想使用gdb调试我的C++程序中的一些错误。我已经在谷歌上搜索到了一些关于在emacs中调试R的资源,如R-FAQ、一些邮件在这里,当然还有R的撰写R扩展手册。

然而,由于我是第一次这样做,因此无法深入了解。是否有人可以给我一些指导,告诉我如何在emacs中调试R包(或带有C ++ / C代码的扩展)。具体来说,我想利用使用ESS与Emacs的gdb(因为R-FAQ提到了这一点)。

请注意,我知道如何仅使用C或C ++程序使用gdb。但我无法将此知识转化为使用gdb进行R和扩展。

2个回答

7
你可以利用RInside(与Rcpp配合得非常好)将调试C++程序的问题转化为纯C++开发和调试任务,从而利用你现有的C++编程知识。
编写一个main() C++函数,使用RInside创建一个R实例,执行R代码(或源R脚本)设置测试用例,然后从main()中调用被测试的函数。
#include <Rcpp.h>
#include <RInside.h>
#include "function_under_test.h"

int main(int argc, char *argv[]) 
{
    using namespace std;
    using namespace Rcpp;

    RInside R(argc, argv);

    string evalstr = R"(
        a <- matrix(c(1,1,1, 1,1,1, 1,1,1), nrow = 3, ncol=3)
    )";
    R.parseEvalQ(evalstr);

    SEXP a = R["a"];

    R["b"] = function_under_test(a);

    evalstr = R"(
        print(b)
    )";
    R.parseEvalQ(evalstr);

    return 0;
}

然后,像以往一样使用gdb调试C++程序,通过在function_under_test()等位置设置断点。

这样做可以避免在R和C++开发环境之间切换,并且不必重新安装R包。


@user39275:C++11支持原始字符串(用“多余”的R表示),这对于封装多行R语句非常有用。这避免了手动转义换行符的麻烦。 - Christian David

1

很不幸,这并不是那么容易的。你需要在ESS、gdb(即Emacs中的gud)和R之间跳转。最好的描述可能仍然是《编写R扩展》(Writing R Extensions),但是最近的主题ESS邮件列表上也讨论了这个问题(请注意,有些回复在主题之外,因此请查看邮件列表存档)。


2
谢谢。不幸的是,我就是您提到的那个帖子中提问的新手(由Bates教授提出,Maechler教授回答)。 :-(。 - suncoolsu
4
我使用命令行中的 R -d gdb,然后输入 r 告诉 gdb 运行 R,再输入 library(pkg),然后按 ctrl-c 进入 gdb,设置断点等操作,没有用 emacs。对我来说,记住符号名称和程序逻辑已经很具有挑战性了,不需要去记忆 emacs / ESS 层。 - Martin Morgan
我认为这是在编写R扩展中提到的方法,不是吗? - Dirk Eddelbuettel
2
此外,我发现在构建R时不进行优化并使用-ggdb调试标志非常有帮助(R扩展程序也可能建议这样做)。在命令提示符下输入:CFLAGS="-ggdb" CXXFLAGS="-ggdb" FFLAGS="-ggdb" ./configure --enable-R-shlib - Jeff

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接