C++ 调试C++;带有使用gdb的Rcpp的R包的代码无法打印带有R_PV的变量值(未知返回类型)

C++ 调试C++;带有使用gdb的Rcpp的R包的代码无法打印带有R_PV的变量值(未知返回类型),c++,r,debugging,gdb,rcpp,C++,R,Debugging,Gdb,Rcpp,我已经在Ubuntu 18.04上使用RStudio创建了一个使用Rcpp的hello world R包,如下所述: My~/.R/Makevars仅包含行 CXXFLAGS=-g -O0 -Wall 在pkg构建期间,我可以看到这些标志被应用 点击断点后,如何在gdb中打印R向量(C++classesCharacterVector或NumericVector的当前值 (gdb)pr_PV(x)(如中所述)显示错误(可能是因为SEXP已包装?): 我的调试会话: R -d gdb --van

我已经在Ubuntu 18.04上使用RStudio创建了一个使用Rcpp的hello world R包,如下所述:

My
~/.R/Makevars
仅包含行

CXXFLAGS=-g -O0 -Wall
在pkg构建期间,我可以看到这些标志被应用

点击断点后,如何在
gdb
中打印R向量(C++classes
CharacterVector
NumericVector
的当前值

(gdb)pr_PV(x)
(如中所述)显示错误(可能是因为SEXP已包装?):

我的调试会话:

R -d gdb --vanilla
(gdb) run
library(RcppTestPkg)
# type Strg + X to break into gdb to set a breakpoint
(gdb) break rcpp_hello_world.cpp:8
(gdb) cont
rcpp_hello_world()
Breakpoint 1, rcpp_hello_world () at rcpp_hello_world.cpp:8
8       NumericVector y   = NumericVector::create( 0.0, 1.0 ) ;
(gdb) n
9       List z            = List::create( x, y ) ;
(gdb) n
11      return z ;
(gdb) info locals
x = {<Rcpp::PreserveStorage<Rcpp::Vector<16, Rcpp::PreserveStorage> >> = {
    data = 0x5555562c4360}, <Rcpp::SlotProxyPolicy<Rcpp::Vector<16, Rcpp::PreserveStorage> >> = {<No data fields>}, <Rcpp::AttributeProxyPolicy<Rcpp::Vector<16, Rcpp::PreserveStorage> >> = {<No data fields>}, <Rcpp::NamesProxyPolicy<Rcpp::Vector<16, Rcpp::PreserveStorage> >> = {<No data fields>}, <Rcpp::RObjectMethods<Rcpp::Vector<16, Rcpp::PreserveStorage> >> = {<No data fields>}, <Rcpp::VectorBase<16, true, Rcpp::Vector<16, Rcpp::PreserveStorage> >> = {<Rcpp::traits::expands_to_logical__impl<16>> = {<No data fields>}, <No data fields>}, cache = {
    p = 0x7fffffffba10}}
y = {<Rcpp::PreserveStorage<Rcpp::Vector<14, Rcpp::PreserveStorage> >> = {
    data = 0x5555562c43d0}, <Rcpp::SlotProxyPolicy<Rcpp::Vector<14, Rcpp::PreserveStorage> >> = {<No data fields>}, <Rcpp::AttributeProxyPolicy<Rcpp::Vector<14, Rcpp::PreserveStorage> >> = {<No data fields>}, <Rcpp::NamesProxyPolicy<Rcpp::Vector<14, Rcpp::PreserveStorage> >> = {<No data fields>}, <Rcpp::RObjectMethods<Rcpp::Vector<14, Rcpp::PreserveStorage> >> = {<No data fields>}, <Rcpp::VectorBase<14, true, Rcpp::Vector<14, Rcpp::PreserveStorage> >> = {<Rcpp::traits::expands_to_logical__impl<14>> = {<No data fields>}, <No data fields>}, cache = {
    start = 0x5555562c43f8}}
z = {<Rcpp::PreserveStorage<Rcpp::Vector<19, Rcpp::PreserveStorage> >> = {
    data = 0x5555562c4440}, <Rcpp::SlotProxyPolicy<Rcpp::Vector<19, Rcpp::PreserveStorage> >> = {<No data fields>}, <Rcpp::AttributeProxyPolicy<Rcpp::Vector<19, Rcpp::PreserveStorage> >> = {<No data fields>}, <Rcpp::NamesProxyPolicy<Rcpp::Vector<19, Rcpp::PreserveStorage> >> = {<No data fields>}, <Rcpp::RObjectMethods<Rcpp::Vector<19, Rcpp::PreserveStorage> >> = {<No data fields>}, <Rcpp::VectorBase<19, true, Rcpp::Vector<19, Rcpp::PreserveStorage> >> = {<Rcpp::traits::expands_to_logical__impl<19>> = {<No data fields>}, <No data fields>}, cache = {
    p = 0x7fffffffbab0}}
(gdb) p x
$3 = {<Rcpp::PreserveStorage<Rcpp::Vector<16, Rcpp::PreserveStorage> >> = {
    data = 0x5555562c4360}, <Rcpp::SlotProxyPolicy<Rcpp::Vector<16, Rcpp::PreserveStorage> >> = {<No data fields>}, <Rcpp::AttributeProxyPolicy<Rcpp::Vector<16, Rcpp::PreserveStorage> >> = {<No data fields>}, <Rcpp::NamesProxyPolicy<Rcpp::Vector<16, Rcpp::PreserveStorage> >> = {<No data fields>}, <Rcpp::RObjectMethods<Rcpp::Vector<16, Rcpp::PreserveStorage> >> = {<No data fields>}, <Rcpp::VectorBase<16, true, Rcpp::Vector<16, Rcpp::PreserveStorage> >> = {<Rcpp::traits::expands_to_logical__impl<16>> = {<No data fields>}, <No data fields>}, cache = {
    p = 0x7fffffffba10}}

(gdb) p R_PV(x)
'R_PV' has unknown return type; cast the call to its declared return type

(gdb) p x->data
$5 = (SEXP) 0x5555566d2308
(gdb) p R_PV(x->data)
'R_PV' has unknown return type; cast the call to its declared return type


R-dgdb——香草
(gdb)运行
库(RcppTestPkg)
#键入Strg+X以进入gdb以设置断点
(gdb)打破rcpp\u hello\u world。cpp:8
(gdb)续
rcpp_你好_世界()
断点1,rcpp_hello_world()位于rcpp_hello_world.cpp:8
8 NumericVector y=NumericVector::create(0.0,1.0);
(gdb)n
9 List z=List::create(x,y);
(gdb)n
11返回z;
(gdb)本地信息
x={={
数据=0x5555562c4360},={},={},={},={},={},={},={={},},缓存={
p=0x7FFFFFBA10}
y={={
数据=0x5555562c43d0},={},={},={},={},={},={},缓存={
开始=0x55562C43F8}
z={={
数据=0x5555562c4440},={},={},={},={},={},={{},={},缓存={
p=0x7FFFFFBAB0}
(gdb)Px
$3 = { = {
数据=0x5555562c4360},={},={},={},={},={},={},={={},},缓存={
p=0x7FFFFFBA10}
(gdb)p R_PV(x)
“R_PV”具有未知的返回类型;将调用强制转换为其声明的返回类型
(gdb)Px->数据
$5=(SEXP)0x5555566d2308
(gdb)PRU PV(x->数据)
“R_PV”具有未知的返回类型;将调用强制转换为其声明的返回类型
编辑:以下是该函数的源代码:

#include <Rcpp.h>
using namespace Rcpp;

// [[Rcpp::export]]
List rcpp_hello_world() {

    CharacterVector x = CharacterVector::create( "foo", "bar" )  ;
    NumericVector y   = NumericVector::create( 0.0, 1.0 ) ;
    List z            = List::create( x, y ) ;

    return z ;
}
#包括
使用名称空间Rcpp;
//[[Rcpp::导出]]
列出rcpp_hello_world(){
CharacterVector x=CharacterVector::创建(“foo”、“bar”);
NumericVector y=NumericVector::create(0.0,1.0);
List z=List::create(x,y);
返回z;
}
(gdb)PRU PV(x)

在我的
R
源代码中,
R\u PV
是一个返回
void
的函数。请尝试以下操作:

(gdb) call R_PV(x)
正如Dirk Eddelbuettel所指出的,您仍然需要将正确的类型传递给
R\u PV
,因此正确的命令可能是:

(gdb) call R_PV(Rcpp::wrap(&x))

R API是由R定义的C类型。您将它指向C++类型。您有两个选项:a)通过<代码> RCPP::Wrp()/<代码>将C++类型转换为<代码>或B)指向C++类型的访问<代码>在StackOverflow上,PS截图大多不受欢迎。您可以复制并粘贴您在那里显示的内容…是的,屏幕截图不好(只是一个玩笑;-)代码是由RStudio创建的原始代码(在我问题的第一句中链接)。@DirkEddelbuettel
Rcpp::wrap
Rcpp::print
gdb
中失败(未找到,例如尝试
调用print时)(x->data)
调用Rcpp::wrap(x)
),因为链接器优化掉了所有未使用的模板实例(
wrap
也可以是内联的)。如果我的代码不使用这些函数,我如何在
gdb
中使用这些函数(是否有使用这些函数在
gdb
中调试的Rcpp最佳实践)?是的。调试器只知道C代码。因此,它允许您查看SEXP,和/或使用您找到的与SEXP类型相关的工具。现在使用
as()
,尤其是
wrap()
,为自己创建一个
SEXP
。是的。它可能需要重新编译,但正如他们所说,“生命是一个b%tch,然后你就死了。”如果你在gdb级别有更好的工具,你将是我的英雄。准确地说。那里有一个
SEXP
,而且
Rf\u PrintValue
知道如何处理。现在,我恐怕没有人留下来了……THX,很好的起点,但我仍然在表达式中遇到语法错误…。学习
gdb
语法和陷阱并不容易…如果gdb说:
调用Rcpp::wrap(x)
->
在名称空间“Rcpp”中没有符号“wrap”
?我还尝试使用了…
&x
…模板函数
wrap
被优化了,因为它没有在我的示例代码中使用…请参阅
(gdb) call R_PV(Rcpp::wrap(&x))