Android ndk 将地址消毒器与android NDK一起使用时出现链接问题

Android ndk 将地址消毒器与android NDK一起使用时出现链接问题,android-ndk,address-sanitizer,Android Ndk,Address Sanitizer,我正在使用Android Studio构建一个包含使用NDK的模块的应用程序。有证据表明内存已损坏,所以我正在NDK开发者网站上尝试地址消毒器。但该应用程序无法构建 我需要(A)确保我的目标是Android 27+(我将minSdkVersion设置为27;我正在为Galaxy S9、SDK 28构建调试构建),以及(B)添加编译器标志,我已经完成了: android { defaultConfig { externalNativeBuild {

我正在使用Android Studio构建一个包含使用NDK的模块的应用程序。有证据表明内存已损坏,所以我正在NDK开发者网站上尝试地址消毒器。但该应用程序无法构建

我需要(A)确保我的目标是Android 27+(我将minSdkVersion设置为27;我正在为Galaxy S9、SDK 28构建调试构建),以及(B)添加编译器标志,我已经完成了:

android {
    defaultConfig {
        externalNativeBuild {
            cmake {
                # Can also use system or none as ANDROID_STL.
                arguments "-DANDROID_ARM_MODE=arm", "-DANDROID_STL=c++_shared"
                cppFlags "-fsanitize=address -fno-omit-frame-pointer"
            }
        }
    }
}
我还根据说明添加了wrap.sh脚本,但我知道它们只在运行时相关

问题是我的应用程序无法生成。输出如下

C++编译器BR> “C:/Users/user/AppData/Local/Android/sdk/ndk bundle/toolschains/llvm/prebuild/windows-x86_64/bin/clang++.exe” 无法编译简单的测试程序

它失败,输出如下:

更改目录: C:/Users/user/studio/app/android/audioengine/.externalNativeBuild/cmake/debug/arm64-v8a/CMakeFiles/cmakemp

运行构建
命令:“C:\Users\user\AppData\Local\Android\sdk\cmake\3.6.4111459\bin\ninja.exe” “CMTC58655”

[1/2]构建CXX对象 cmakfiles/cmtc58655.dir/testcxcompiler.cxx.o

[2/2]链接CXX可执行文件CMTC58655

失败:cmd.exe/C“cd.&&
C:\Users\user\AppData\Local\Android\sdk\ndk bundle\toolschains\llvm\prebuild\windows-x86\u 64\bin\clang++.exe --target=aarch64-none-linux-android27--gcc toolchain=C:/Users/user/AppData/Local/Android/sdk/ndk bundle/toolchains/llvm/prebuild/windows-x86_64 --sysroot=C:/Users/user/AppData/Local/Android/sdk/ndk bundle/toolschains/llvm/prebuild/windows-x86_64/sysroot -g-DANDROID-fdata sections-ffunction sections-funwind tables-fstack protector strong-无规范前缀-fno addrsig-Wa,--noexecstack-Wformat-Werror=格式安全性-stdlib=libc++-fsanize=address-fno省略帧指针-Wl,-排除libs,libgcc.a-Wl,-排除libs,libatomic.a-Wl,--构建id-Wl,--警告共享textrel-Wl,--致命警告-Wl,-无未定义-使用的参数-Wl,-z,noexecstack-Wl,-z,relro-Wl,-z,now-Wl,-gc节CMakeFiles/cmtc58655.dir/testCXXCompiler.cxx.o-o cmTC_58655-latomic-lm&&cd。“

C:/Users/user/AppData/Local/Android/sdk/ndk bundle/toolschains/llvm/prebuild/windows-x86_64/lib/gcc/aarch64 linux-Android/4.9.x/../../../../../../../aarch64 linux-Android/bin\ld: 警告:liblog.so,由
C:\Users\tim\AppData\Local\Android\sdk\ndk bundle\toolschains\llvm\prebuild\windows-x86\u 64\lib64\clang\8.0.2\lib\linux\libclang\rt.asan-aarch64-Android.so, 找不到(请尝试使用-rpath或-rpath链接)

clang++.exe:错误:链接器命令失败,退出代码为1(使用-v 查看调用)

编译器标志已正确传递。有一个关于liblog.so的警告未找到,但随后出现了一个非特定错误

说明显示了在项目中放置消毒剂库的位置(在jniLibs文件夹中),但没有显示它们的来源。我从我机器上的NDK安装中复制了它们。我试着用liblog库做同样的事情,但不清楚使用哪种变体;我尝试的那个(SDK 28)并没有影响结果


我错过了什么?我发现一些帖子在理解如何使用地址消毒剂方面遇到了困难,但没有一篇文章提到这个问题。

看起来那些文档是错的。在执行该测试时,CMake似乎没有使用它需要的所有链接器标志。我不确定这是NDK bug还是CMake bug,但有一种方法可以让ASan与CMake/gradle一起工作:

  • 从build.gradle中删除
    cppFlags
    部分
  • 将这些选项添加到CMakeLists.txt中,如下所示:

    add_library(app SHARED app.cpp)
    target_compile_options(app PUBLIC -fsanitize=address -fno-omit-frame-pointer)
    set_target_properties(app PROPERTIES LINK_FLAGS -fsanitize=address)
    

  • 我上传了一个修改来修复文档。应该很快就会上线。

    现在我可以构建我的应用程序了。但是加载wrap.sh失败:“正在执行/data/app/fm.x.x-dlmu0mshppv3ajlkaqbxw==/lib/arm/wrap.sh失败:没有这样的文件或目录。”指令说要将wrap.sh脚本和libclang_rt.asan-…-android.so文件放在“项目的应用程序模块”中非常特定的文件夹中——它们都不是一个名为“arm”的文件夹。我的所有本机代码都位于单独的(非应用程序)模块中,其库位于与此相关的不同文件夹位置。wrap.sh和libclang_rt.asan-…-android.so文件应该放在哪里?回答我自己的评论:我在应用程序和模块中都包含了wrap.sh脚本和libclang_rt.asan-…-android.so,其中包含了我的本地代码。检查两人是否都进入了apk。然后我发现根本的问题是wrap.sh中的行尾错误(我使用的是WIndows,它需要Unix风格)。我希望这对其他人有帮助。