我正在尝试调试Rcpp
运行时编译的代码。很长一段时间以来,我一直试图让它发挥作用,但没有成功。
这里提出了一个非常相似的问题:Windows下Rcpp生成的DLL的调试(逐行)它问了同样的问题,但问题和答案都远远超出了我的理解。
这是我所拥有的:
Windows 7 Pro SP1
R 3.5
Rstudio 1.1.463 with Rcpp.
Rbuild Tools from Rstudio. (c++ compiler)
程序:
在 Rstudio 文件 -> 新文件 -> C++ 文件中(使用 timesTwo 函数创建示例文件。)
我在此文件中添加了一个新函数:
// [[Rcpp::export]]
NumericVector timesTwo2(NumericVector x) {
for(int ii = 0; ii <= x.size(); ii++)
{
x.at(ii) = x.at(ii) * 2;
}
return x;
}
我在“保存”上检查了“源”并将文件另存为 RcppTest.cpp,该文件成功获取或编译了该文件。
在 Rstudio 中运行代码:
data = c(1:10)
data
[1] 1 2 3 4 5 6 7 8 9 10
timesTwo2(data)
Error in timesTwo2(data) : Index out of bounds: [index=10; extent=10].
该错误是因为在 for 循环中是<= x.size()
所以结果是一个运行时错误。
问题是如何获得有关此错误的调试输出,合理地告诉我发生了什么?
至少我想知道代码中触发异常的行以及使用哪些参数。
此外,我真的很想在异常发生之前逐行执行代码,这样我就可以准确监控正在发生的情况。
我可以安装任何其他程序或应用任何其他设置,只要我能找到有关如何执行此操作的精确详细信息。现在我从头开始只是为了让它发挥作用。谢谢。
Update:我找到了这个网站:使用 gdb 调试 Rcpp C++ 代码我安装了最新的gcc
8.1 与gdb
我找到了CXXFLAGS
in the makeconf
文件位于C:\Program Files\R\R-3.5.1\etc\x64
然后我开始了Rgui
按照建议,但是当我尝试时Rcpp:::sourceCpp
我收到错误:
> library(Rcpp)
> Rcpp::sourceCpp('Rcpptest.cpp')
C:/PROGRA~1/R/R-35~1.1/etc/x64/Makeconf:230: warning: overriding recipe for target '.m.o'
C:/PROGRA~1/R/R-35~1.1/etc/x64/Makeconf:223: warning: ignoring old recipe for target '.m.o'
c:/Rtools/mingw_64/bin/g++ -I"C:/PROGRA~1/R/R-35~1.1/include" -DNDEBUG -I"C:/Users/Michael/Documents/R/win-library/3.5/Rcpp/include" -I"C:/PROGRA~1/R/R-35~1.1/bin/x64" -ggdb -O0 -Wall -gdwarf-2 -mtune=generic -c Rcpptest.cpp -o Rcpptest.o
process_begin: CreateProcess(NULL, c:/Rtools/mingw_64/bin/g++ -IC:/PROGRA~1/R/R-35~1.1/include -DNDEBUG -IC:/Users/Michael/Documents/R/win-library/3.5/Rcpp/include -IC:/PROGRA~1/R/R-35~1.1/bin/x64 -ggdb -O0 -Wall -gdwarf-2 -mtune=generic -c Rcpptest.cpp -o Rcpptest.o, ...) failed.
make (e=2): The system cannot find the file specified.
make: *** [C:/PROGRA~1/R/R-35~1.1/etc/x64/Makeconf:215: Rcpptest.o] Error 2
Error in Rcpp::sourceCpp("Rcpptest.cpp") :
Error 1 occurred building shared library.
WARNING: The tools required to build C++ code for R were not found.
Please download and install the appropriate version of Rtools:
http://cran.r-project.org/bin/windows/Rtools/
看起来正在加载新的CXXFLAGS
它正在使用DEBUG
,但是好像还是无法编译。有人知道错误的原因吗?
我尝试以相同的方式运行 RstudioRgui
它开始于许多线程显示在gdb
窗口,但 Rstudio 中的所有内容都像以前一样运行,没有来自 Rstudio 或的附加调试信息gdb
.
更新2:正如上面的错误指出的那样Rgui
没有用于编译的 Rtools,因此我从提供的链接安装了 Rtools。它安装在 C:\Rtools 中,而 Rstudio 安装在 C:\RBuildTools 中。所以我现在有 3 个编译器,Rtools、RbuildTools 和gcc
with gdb
。
现在可以编译了,但仍然出现与我在 Rstudio 中相同的错误。我希望至少获得更好的错误输出,例如传递的行和值。
指令说Rgui
应该有一个断点,但我找不到这样的选项。
Update 3我终于能够设置并运行 Linux 安装(Ubuntu 16.04.05)。
首先这是我的CXXFLAGS
:
$ R CMD config CXXFLAGS
-g -O0 -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2 -g
我必须创建一个.R
我的主目录中的文件夹和Makevar
文件中只包含一行
CXXFLAGS = -g -O0 -Wall -pedantic -fstack-protector-strong -D_FORTIFY_SOURCE=2
仅此一项就花了几个小时,因为它实际上没有说创建文件夹和文件。
然后我在断点处执行了 Ralf 发布的命令:
> timesTwo2(d1)
Thread 1 "R" hit Breakpoint 1, timesTwo2 (x=...) at RcppTest.cpp:19
19 NumericVector timesTwo2(NumericVector x) {
(gdb) n
20 for (int ii = 0; ii <= x.size(); ii++)
(gdb) n
22 x.at(ii) = x.at(ii) * 2;
(gdb) display ii
1: ii = 0
(gdb) n
20 for (int ii = 0; ii <= x.size(); ii++)
1: ii = 0
(gdb) n
22 x.at(ii) = x.at(ii) * 2;
1: ii = 1
(gdb) n
20 for (int ii = 0; ii <= x.size(); ii++)
1: ii = 1
(gdb) display x.at(ii)
2: x.at(ii) = <error: Attempt to take address of value not located in memory.>
(gdb) n
22 x.at(ii) = x.at(ii) * 2;
1: ii = 2
2: x.at(ii) = <error: Attempt to take address of value not located in memory.>
(gdb)
最后在n = 10
:
1: ii = 10
2: x.at(ii) = <error: Attempt to take address of value not located in memory.>
(gdb) n
0x00007ffff792d762 in Rf_applyClosure () from /usr/lib/R/lib/libR.so
(gdb)
这绝对是我调试的最远的地方,但这是一个非常基本的功能,调试输出甚至错误输出都不是很有用。它给了我它正在执行的行,它可以显示 ii,但我无法显示数组值或整个数组。是否可以创建一个更具体的断点,使其仅在以下情况下中断:ii == 10
?
理想情况下,我希望在 Rstudio 或其他可以显示整个向量的 GUI 中使用它。仍在做更多测试。