Как отлаживать пакет R (с кодом C) в Emacs с помощью GDB?

В настоящее время я пишу пакет R и использую скомпилированный код C++ через пакет Rcpp в R (Rcpp упрощает взаимодействие кода R и C++ для таких непрограммистов, как я, ИМХО).

Я хочу отладить несколько ошибок в моей программе на C++, используя gdb. Я погуглил и нашел в основном несколько ресурсов по отладке R в emacs, R-FAQ, несколько писем здесь и, конечно же, в R Writer Extension Manual.

Впрочем, я делаю это впервые, я не мог переборщить. Может ли кто-нибудь дать мне несколько советов о том, как отлаживать пакеты R (или расширения с кодом C++/C) в emacs. В частности, я хочу воспользоваться преимуществами использования ESS с R и gdb с Emacs (о чем говорится в R-FAQ).

Обратите внимание, я могу использовать gdb, используя только программы на C или C++. Но я не смог перенести эти знания на использование gdb с R и расширениями.


person suncoolsu    schedule 12.02.2011    source источник


Ответы (2)


Вы можете использовать имеющиеся у вас знания об отладке программ на C++, превратив проблему в задачу разработки и отладки на чистом C++ с помощью RInside (отличный помощник для Rcpp).

Напишите функцию main() C++, которая создает экземпляр R с помощью RInside, выполняет код 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;
}

Затем действуйте как обычно при отладке программы на C++ с помощью gdb, установив точки останова в function_under_test() и т. д.

Таким образом, вы избегаете переключения между средами разработки R и C++ и необходимости переустанавливать пакет R.

person Christian David    schedule 07.11.2012
comment
@ user39275: C++11 поддерживает необработанные строки (обозначаемые посторонним R), которые полезны для инкапсуляции многострочных операторов R. Это позволяет избежать необходимости экранировать разрывы строк вручную. - person Christian David; 11.04.2013

Не все так просто, к сожалению. Вам нужно переключаться между ESS, gdb (т.е. gud в Emacs) и R. Лучшее описание, вероятно, по-прежнему — это win Написание расширений R, однако там был последняя тема на Список рассылки ESS, в котором это тоже обсуждается (обратите внимание, что некоторые ответы пришли вне темы, так что посмотрите также архив списка рассылки).

person Dirk Eddelbuettel    schedule 12.02.2011
comment
Спасибо. К сожалению, я был новичком, задавшим вопрос в теме (вопрос профессора Бейтса, на который ответил профессор Махлер), который вы упомянули. :-(. - person suncoolsu; 13.02.2011
comment
Я использую R -d gdb из командной строки, затем r, чтобы указать gdb на (r)un R, library(pkg), затем ctrl-c, чтобы ворваться в gdb, установить точки останова и т. д., то есть без emacs. Держать в голове имена символов и логику программы для меня достаточно сложно, без необходимости помнить про слой emacs/ESS. - person Martin Morgan; 13.02.2011
comment
Я думаю, что это подход, описанный в Writing R Extensions, не так ли? - person Dirk Eddelbuettel; 13.02.2011
comment
Кроме того, я считаю очень полезным собрать R без оптимизации и с флагами отладки -ggdb (расширения R также могут предлагать это). В командной строке: CFLAGS=-ggdb CXXFLAGS=-ggdb FFLAGS=-ggdb ./configure --enable-R-shlib - person Jeff; 13.02.2011