Earlier this week I figured out how to turn on assertion errors for debugging Eigen C++ code in an R package, which results in crashes with incomprehensible messages like

R: /home/tdhock/R/i686-pc-linux-gnu-library/3.5/RcppEigen/include/Eigen/src/Core/CwiseBinaryOp.h:110: Eigen::CwiseBinaryOp<BinaryOp, Lhs, Rhs>::CwiseBinaryOp(const Lhs&, const Rhs&, const BinaryOp&) [with BinaryOp = Eigen::internal::scalar_difference_op<double, double>; LhsType = const Eigen::Block<Eigen::Map<Eigen::Matrix<double, -1, -1> >, 1, -1, false>; RhsType = const Eigen::Map<Eigen::Matrix<double, -1, 1> >; Eigen::CwiseBinaryOp<BinaryOp, Lhs, Rhs>::Lhs = Eigen::Block<Eigen::Map<Eigen::Matrix<double, -1, -1> >, 1, -1, false>; Eigen::CwiseBinaryOp<BinaryOp, Lhs, Rhs>::Rhs = Eigen::Map<Eigen::Matrix<double, -1, 1> >]: Assertion `aLhs.rows() == aRhs.rows() && aLhs.cols() == aRhs.cols()' failed.

To get a more informative message I used gdb. First I tell the compiler to save debugging info via the -g flag, added in the src/Makevars file:

PKG_CPPFLAGS=-UNDEBUG -g

Then I use the -d flag to tell R to start with the gdb debugger, and the -e flag to run my test R script:

R -d gdb -e 'source("../tests/testthat/test-knn.R")'

That gives me a gdb command line. run starts R, then I get another prompt after R crashes:

> source("../tests/testthat/test-knn.R")
R: ... : Assertion `aLhs.rows() == aRhs.rows() && aLhs.cols() == aRhs.cols()' failed.

Program received signal SIGABRT, Aborted.
0x00007ffff5b31214 in raise ()
   from /cvmfs/soft.computecanada.ca/nix/var/nix/profiles/16.09/lib/libc.so.6
(gdb) 

bt 10 gives me the 10 highest frames in the stack. The relevant lines (in my code) are:

#6  Predict1toMaxNeighbors (train_inputs_ptr=0x2,
    train_label_ptr=0x7ffffffe6580, nrow=0, ncol=-1, max_neighbors=0,
    test_input_ptr=0x7ffffffe6580, test_prediction_ptr=0xbe1f400)
    at knn.cpp:32
#7  0x00007fffe164e5ca in Predict1toMaxNeighbors_interface(double*, double*, int*, int*, int*, double*, double*) ()
   from /home/thocking/R/x86_64-pc-linux-gnu-library/3.5/nearestNeighbors/libs/nearestNeighbors.so

From frame #6 we see that the assertion was raised on line 32 of knn.cpp.

f 6 shows the line of code responsible:

(gdb) f 6
#6  Predict1toMaxNeighbors (train_inputs_ptr=0x2,
    train_label_ptr=0x7ffffffe6580, nrow=0, ncol=-1, max_neighbors=0,
    test_input_ptr=0x7ffffffe6580, test_prediction_ptr=0xbe1f400)
    at knn.cpp:32
32          distance_vec(i) = (train_inputs_mat.row(i)-test_input_vec).norm();
(gdb) 

Then normally p can be used to print the values of the variables in that frame, but it did not work for me:

(gdb) p i
$1 = <optimized out>
(gdb) p test_input_vec
$2 = <optimized out>

Anyway, having the line number where the assertion happened is extremely useful. Once I know the line number, I can use std::cout to print values of variables on that line, after recompiling.