I am trying to debug Rcpp
compiled code at run-time. I have been trying to get this to work unsuccessfully, for a very long time.
A very similar question was as
It can be done with Visual Studio Code, since it can handle both R
and C++
. This allows you to step through your Rcpp
code one line at a time in a GUI environment.
See this demo to get started.
The usual approach R -d gdb
, which I also suggested in my original answer below, does not work on Windows:
--debugger=name
-d name(UNIX only) Run R through debugger name. For most debuggers (the exceptions are valgrind and recent versions of gdb), further command line options are disregarded, and should instead be given when starting the R executable from inside the debugger.
https://cran.r-project.org/doc/manuals/r-release/R-intro.html#Invoking-R-from-the-command-line
Alternative:
gdb.exe Rgui.exe
break TimesTwo2
run
Rcpp::sourceCpp("debug.cpp")
next
, print
, display
to step through the code.An alternative to step 1. would be to start R, get the PID with Sys.getpid()
, attach debugger with gdb -p <pid>
. You will than have to use continue
instead of run
.
I don't have a Windows machine right now, so the following was done on Linux. I hope it is transferable, though. Let's start with a simple cpp file (debug.cpp
in my case) that contains your code:
#include <Rcpp.h>
using Rcpp::NumericVector;
// [[Rcpp::export]]
NumericVector timesTwo2(NumericVector x) {
for(int ii = 0; ii <= x.size(); ii++)
{
x.at(ii) = x.at(ii) * 2;
}
return x;
}
/*** R
data = c(1:10)
data
timesTwo2(data)
*/
I can reproduce the error by calling R on the command line:
$ R -e "Rcpp::sourceCpp('debug.cpp')"
R version 3.5.1 (2018-07-02) -- "Feather Spray"
[...]
> Rcpp::sourceCpp('debug.cpp')
> 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].
Calls: <Anonymous> ... source -> withVisible -> eval -> eval -> timesTwo2 -> .Call
Execution halted
Next we can start R with gdb
as debugger (c.f. Writing R Extensions as Dirk said):
$ R -d gdb -e "Rcpp::sourceCpp('debug.cpp')"
GNU gdb (Debian 8.2-1) 8.2
[...]
(gdb) break timesTwo2
Function "timesTwo2" not defined.
Make breakpoint pending on future shared library load? (y or [n]) y
Breakpoint 1 (timesTwo2) pending.
(gdb) run
[...]
> Rcpp::sourceCpp('debug.cpp')
[Thread 0xb40d3b40 (LWP 31793) exited]
[Detaching after fork from child process 31795]
> data = c(1:10)
> data
[1] 1 2 3 4 5 6 7 8 9 10
> timesTwo2(data)
Thread 1 "R" hit Breakpoint 1, 0xb34f3310 in timesTwo2(Rcpp::Vector<14, Rcpp::PreserveStorage>)@plt ()
from /tmp/RtmphgrjLg/sourceCpp-i686-pc-linux-gnu-1.0.0/sourcecpp_7c2d7f56744b/sourceCpp_2.so
(gdb)
At this point you can single step through the program using next
(or just n
) and output variables using print
(or just p
). A useful command is also display
:
Thread 1 "R" hit Breakpoint 1, timesTwo2 (x=...) at debug.cpp:5
5 NumericVector timesTwo2(NumericVector x) {
(gdb) n
6 for(int ii = 0; ii <= x.size(); ii++)
(gdb) n
8 x.at(ii) = x.at(ii) * 2;
(gdb) display ii
2: ii = 0
(gdb) n
8 x.at(ii) = x.at(ii) * 2;
2: ii = 0
[...]
2: ii = 9
(gdb)
46 inline proxy ref(R_xlen_t i) { return start[i] ; }
2: ii = 9
(gdb)
6 for(int ii = 0; ii <= x.size(); ii++)
2: ii = 10
(gdb)
8 x.at(ii) = x.at(ii) * 2;
2: ii = 10
(gdb)
Error in timesTwo2(data) : Index out of bounds: [index=10; extent=10].
Calls: <Anonymous> ... source -> withVisible -> eval -> eval -> timesTwo2 -> .Call
Execution halted
[Detaching after fork from child process 32698]
[Inferior 1 (process 32654) exited with code 01]
BTW, I used the following compile flags:
$ R CMD config CXXFLAGS
-g -O2 -Wall -pedantic -fstack-protector-strong -D_FORTIFY_SOURCE=2
You might want to switch to -O0
.