构建 R 包以使用 ASAN

问题描述 投票:0回答:1

背景:我正在开发一个使用 Rcpp 并包含一些 C++ 文件的包。我想用 ASAN 分析我的代码。我正在努力构建我的包。

到目前为止我做了什么

  1. 我正在使用
    https://hub.docker.com/r/rocker/r-devel-san
    docker 容器,该容器附带预构建的 R(或 RD)来与 ASAN 配合使用。
  2. 在此容器中,我可以运行带有
    -fsanitize=address
    标志的 C++ 脚本以获得有意义的 ASAN 输出。
  3. 我的
    src/Makevars
    文件如下所示(并非所有标志都与此问题相关):
CC = gcc -fsanitize=address -fno-omit-frame-pointer
CXX = g++
LDFLAGS = -fsanitize=address
PKG_CXXFLAGS = -fsanitize=address -fno-omit-frame-pointer -fno-sanitize-address-use-after-scope -D_GCL_RHACK_ -DGC_NO_MUTEX -m64 -ldl -lpthread -Wall -pipe -pedantic -Wno-unused -DNDEBUG -g -std=c++17
PKG_CFLAGS = -fsanitize=address -D_GCL_RHACK_ -fno-sanitize-address-use-after-scope
  1. 要安装,我这样做(从包含我的包目录的目录
    foo
    ):
RD CMD build foo
RD CMD install -l temp_lib/ foo_1.0.tar.gz

安装命令抛出以下错误(以及构建的最后一行)

-g -O2  -c loadpathutil.c -o loadpathutil.o
g++ -fsanitize=undefined,bounds-strict -fno-omit-frame-pointer -std=gnu++17 -shared -L/usr/local/lib/R/lib -L/usr/local/lib -o foo.so RcppExports.o Read.o Utilities.o Write.o gdxcc.o loadpathutil.o -L/usr/local/lib/R/lib -lR
** R
** byte-compile and prepare package for lazy loading
** help
*** installing help indices
** building package indices
** testing if installed package can be loaded from temporary location
Error: package or namespace load failed for ‘foo’ in dyn.load(file, DLLpath = DLLpath, ...):
installing to /work/temp_lib/00LOCK-foo/00new/foo/libs

unable to load shared object '/work/temp_lib/00LOCK-foo/00new/foo/libs/foo.so':
  /work/temp_lib/00LOCK-foo/00new/foo/libs/foo.so: undefined symbol: __asan_option_detect_stack_use_after_return

我知道最终的包共享对象必须以某种方式链接到ASAN,但建议的解决方案

LDFLAGS
PKG_LDFLAGS
似乎没有帮助。

r rcpp address-sanitizer
1个回答
0
投票

这是我为自己编写并自己使用的文档。

  1. 下载并解压缩R源代码
  2. 安装编译器
    clang
    apt-get install clang
    应该完成这项工作
  3. 打开
    config.site
    并在末尾添加以下内容
## clang-ASAN, clang-UBSAN:
CC="clang -fsanitize=address,undefined -fno-sanitize=float-divide-by-zero -fno-sanitize=alignment -fno-omit-frame-pointer"
CXX="clang++ -fsanitize=address,undefined -fno-sanitize=float-divide-by-zero -fno-sanitize=alignment -fno-omit-frame-pointer -frtti"
CFLAGS="-g -O3 -Wall -pedantic"
FFLAGS="-g -O2 -mtune=native"
CXXFLAGS="-g -O3 -Wall -pedantic"
MAIN_LD="clang++ -fsanitize=undefined,address"

export ASAN_OPTIONS='detect_leaks=0:detect_odr_violation=0'
export UBSAN_OPTIONS='print_stacktrace=1'
export RGL_USE_NULL="true"
export R_DONT_USE_TK="true"
  1. 奔跑
./configure \
    --prefix=/opt/R/${R_VERSION} \
    --enable-memory-profiling \
    --enable-R-shlib \
    --with-blas \
    --with-lapack
  1. 奔跑
    make

然后我们可以通过在

bin/R
中运行R并使用包
sanitizers
触发错误来检查它是否真的有效。

install.packages("sanitizers")
sanitizers::stackAddressSanitize(42)
sanitizers::heapAddressSanitize(10)
© www.soinside.com 2019 - 2024. All rights reserved.