Rcpp::stop() 在 g++ 下使 R 崩溃
Rcpp::stop() crashes R under g++
这是一个调用 Rcpp::stop()
的简单测试函数
#include <Rcpp.h>
NumericVector dostop()
{
Rcpp::stop("foo");
NumericVector x(1);
return x;
}
在 OS X 上有 clang 时,这按预期执行:
> library(Rcpp)
> sourceCpp('stop.cpp')
> dostop()
Error in dostop() : foo
>
然而,在 Linux 上使用 g++,此函数崩溃 R:
> library(Rcpp)
> sourceCpp('stop.cpp')
> dostop()
*** glibc detected *** /share/apps/R/3.3.3/lib64/R/bin/exec/R: free(): invalid pointer: 0x0000000001c29ff8 ***
======= Backtrace: =========
/lib64/libc.so.6[0x3407c75f4e]
/lib64/libc.so.6[0x3407c78cad]
/tmp/RtmpiUT8Xb/sourceCpp-x86_64-pc-linux-gnu-1.0.1/sourcecpp_7dc862cd8f07/sourceCpp_2.so(_Z31exception_to_condition_templateIN4Rcpp9exceptionEEP7SEXPRECRKT_b+0x1da)[0x7f6fab831287]
/tmp/RtmpiUT8Xb/sourceCpp-x86_64-pc-linux-gnu-1.0.1/sourcecpp_7dc862cd8f07/sourceCpp_2.so(_Z29rcpp_exception_to_r_conditionRKN4Rcpp9exceptionE+0x29)[0x7f6fab83073d]
/tmp/RtmpiUT8Xb/sourceCpp-x86_64-pc-linux-gnu-1.0.1/sourcecpp_7dc862cd8f07/sourceCpp_2.so(sourceCpp_1_dostop+0x27d)[0x7f6fab82dd02]
/share/apps/R/3.3.3/lib64/R/lib/libR.so(+0xdc4fe)[0x7f6fb4ea04fe]
(and many more lines of similar)
这里是相关的会话信息:
> sessionInfo()
R version 3.3.3 (2017-03-06)
Platform: x86_64-pc-linux-gnu (64-bit)
Running under: Red Hat Enterprise Linux Workstation release 6.6 (Santiago)
locale:
[1] LC_CTYPE=en_US.UTF-8 LC_NUMERIC=C
[3] LC_TIME=en_US.UTF-8 LC_COLLATE=en_US.UTF-8
[5] LC_MONETARY=en_US.UTF-8 LC_MESSAGES=en_US.UTF-8
[7] LC_PAPER=en_US.UTF-8 LC_NAME=C
[9] LC_ADDRESS=C LC_TELEPHONE=C
[11] LC_MEASUREMENT=en_US.UTF-8 LC_IDENTIFICATION=C
attached base packages:
[1] stats graphics grDevices utils datasets methods base
other attached packages:
[1] Rcpp_1.0.1
问题 1:我应该正确使用 Rcpp::stop()
吗?也就是说,我是否应该像 OS X 案例那样调用它并在控制台收到错误消息?
问题 2:如果是这样,对于我在 Linux/g++ 上看到的绝对次优行为,是否有任何解决方法?
简要回答:
问题 1
您正在正确使用 Rcpp::stop()
。但是你的系统已经有好几年了,落后了几个 R 版本,我们制作了几十个 (!!) Rcpp 版本,因为它是最新的。 stone-old R 和编译器与当前 Rcpp 的组合很少见。
问题 2
升级到当前版本,或者坚持使用我们在那些 R 和 g++ 版本规则时制作的旧版本。也许尝试 Rcpp 版本 0.12.* 或 0.13.*.
例子
当前 OS 和编译器版本:
> Rcpp::cppFunction('double doStop(NumericVector x) { stop("foo"); return x[1]; }')
> doStop(c(1.2, 3.4))
Error in doStop(c(1.2, 3.4)) : foo
>
> sessionInfo()
R version 3.6.0 (2019-04-26)
Platform: x86_64-pc-linux-gnu (64-bit)
Running under: Ubuntu 18.10
Matrix products: default
BLAS: /usr/lib/x86_64-linux-gnu/openblas/libblas.so.3
LAPACK: /usr/lib/x86_64-linux-gnu/libopenblasp-r0.3.3.so
locale:
[1] LC_CTYPE=en_US.UTF-8 LC_NUMERIC=C
[3] LC_TIME=en_US.UTF-8 LC_COLLATE=en_US.UTF-8
[5] LC_MONETARY=en_US.UTF-8 LC_MESSAGES=en_US.UTF-8
[7] LC_PAPER=en_US.UTF-8 LC_NAME=C
[9] LC_ADDRESS=C LC_TELEPHONE=C
[11] LC_MEASUREMENT=en_US.UTF-8 LC_IDENTIFICATION=C
attached base packages:
[1] stats graphics grDevices utils datasets methods base
loaded via a namespace (and not attached):
[1] compiler_3.6.0 tools_3.6.0 Rcpp_1.0.1
>
我运行 最近在centos 7.3 和R 3.6 下遇到这个问题。您可能正在使用 gcc >= 5.1 的版本以及相关的 libstdc++,而您的 glibc 版本是 <= 2.17.
在此上下文中,最好使用 -D_GLIBCXX_USE_CXX11_ABI=0 标志编译 C++11 代码以使其正常工作。
您可以添加
CXXFLAGS=-D_GLIBCXX_USE_CXX11_ABI=0
在您的 ~/.R/Makevars 文件中并重新安装 Rcpp。改完后没发现什么问题
这是一个调用 Rcpp::stop()
#include <Rcpp.h>
NumericVector dostop()
{
Rcpp::stop("foo");
NumericVector x(1);
return x;
}
在 OS X 上有 clang 时,这按预期执行:
> library(Rcpp)
> sourceCpp('stop.cpp')
> dostop()
Error in dostop() : foo
>
然而,在 Linux 上使用 g++,此函数崩溃 R:
> library(Rcpp)
> sourceCpp('stop.cpp')
> dostop()
*** glibc detected *** /share/apps/R/3.3.3/lib64/R/bin/exec/R: free(): invalid pointer: 0x0000000001c29ff8 ***
======= Backtrace: =========
/lib64/libc.so.6[0x3407c75f4e]
/lib64/libc.so.6[0x3407c78cad]
/tmp/RtmpiUT8Xb/sourceCpp-x86_64-pc-linux-gnu-1.0.1/sourcecpp_7dc862cd8f07/sourceCpp_2.so(_Z31exception_to_condition_templateIN4Rcpp9exceptionEEP7SEXPRECRKT_b+0x1da)[0x7f6fab831287]
/tmp/RtmpiUT8Xb/sourceCpp-x86_64-pc-linux-gnu-1.0.1/sourcecpp_7dc862cd8f07/sourceCpp_2.so(_Z29rcpp_exception_to_r_conditionRKN4Rcpp9exceptionE+0x29)[0x7f6fab83073d]
/tmp/RtmpiUT8Xb/sourceCpp-x86_64-pc-linux-gnu-1.0.1/sourcecpp_7dc862cd8f07/sourceCpp_2.so(sourceCpp_1_dostop+0x27d)[0x7f6fab82dd02]
/share/apps/R/3.3.3/lib64/R/lib/libR.so(+0xdc4fe)[0x7f6fb4ea04fe]
(and many more lines of similar)
这里是相关的会话信息:
> sessionInfo()
R version 3.3.3 (2017-03-06)
Platform: x86_64-pc-linux-gnu (64-bit)
Running under: Red Hat Enterprise Linux Workstation release 6.6 (Santiago)
locale:
[1] LC_CTYPE=en_US.UTF-8 LC_NUMERIC=C
[3] LC_TIME=en_US.UTF-8 LC_COLLATE=en_US.UTF-8
[5] LC_MONETARY=en_US.UTF-8 LC_MESSAGES=en_US.UTF-8
[7] LC_PAPER=en_US.UTF-8 LC_NAME=C
[9] LC_ADDRESS=C LC_TELEPHONE=C
[11] LC_MEASUREMENT=en_US.UTF-8 LC_IDENTIFICATION=C
attached base packages:
[1] stats graphics grDevices utils datasets methods base
other attached packages:
[1] Rcpp_1.0.1
问题 1:我应该正确使用 Rcpp::stop()
吗?也就是说,我是否应该像 OS X 案例那样调用它并在控制台收到错误消息?
问题 2:如果是这样,对于我在 Linux/g++ 上看到的绝对次优行为,是否有任何解决方法?
简要回答:
问题 1
您正在正确使用 Rcpp::stop()
。但是你的系统已经有好几年了,落后了几个 R 版本,我们制作了几十个 (!!) Rcpp 版本,因为它是最新的。 stone-old R 和编译器与当前 Rcpp 的组合很少见。
问题 2
升级到当前版本,或者坚持使用我们在那些 R 和 g++ 版本规则时制作的旧版本。也许尝试 Rcpp 版本 0.12.* 或 0.13.*.
例子
当前 OS 和编译器版本:
> Rcpp::cppFunction('double doStop(NumericVector x) { stop("foo"); return x[1]; }')
> doStop(c(1.2, 3.4))
Error in doStop(c(1.2, 3.4)) : foo
>
> sessionInfo()
R version 3.6.0 (2019-04-26)
Platform: x86_64-pc-linux-gnu (64-bit)
Running under: Ubuntu 18.10
Matrix products: default
BLAS: /usr/lib/x86_64-linux-gnu/openblas/libblas.so.3
LAPACK: /usr/lib/x86_64-linux-gnu/libopenblasp-r0.3.3.so
locale:
[1] LC_CTYPE=en_US.UTF-8 LC_NUMERIC=C
[3] LC_TIME=en_US.UTF-8 LC_COLLATE=en_US.UTF-8
[5] LC_MONETARY=en_US.UTF-8 LC_MESSAGES=en_US.UTF-8
[7] LC_PAPER=en_US.UTF-8 LC_NAME=C
[9] LC_ADDRESS=C LC_TELEPHONE=C
[11] LC_MEASUREMENT=en_US.UTF-8 LC_IDENTIFICATION=C
attached base packages:
[1] stats graphics grDevices utils datasets methods base
loaded via a namespace (and not attached):
[1] compiler_3.6.0 tools_3.6.0 Rcpp_1.0.1
>
我运行 最近在centos 7.3 和R 3.6 下遇到这个问题。您可能正在使用 gcc >= 5.1 的版本以及相关的 libstdc++,而您的 glibc 版本是 <= 2.17.
在此上下文中,最好使用 -D_GLIBCXX_USE_CXX11_ABI=0 标志编译 C++11 代码以使其正常工作。
您可以添加
CXXFLAGS=-D_GLIBCXX_USE_CXX11_ABI=0
在您的 ~/.R/Makevars 文件中并重新安装 Rcpp。改完后没发现什么问题