使用 Address Sanitizer 编译主机应用程序时可使用 OpenCL

Mar*_*ang 6 c++ debugging opencl address-sanitizer

我正在调试 OpenCL 应用程序的崩溃。我试图使用 asan 来确定问题的根源。但是后来我发现打开asan并重新编译后,我的应用程序找不到任何OpenCL设备。简单地添加-fsanitize=address到编译器选项使我的程序无法使用 OpenCL。

通过进一步测试,我发现内存清理器不适用于 OpenCL。

为什么会这样?如何在 OpenCL 中使用 asan?

编辑:一个最小的例子

#include <CL/cl.hpp>
#include <vector>
#include <iostream>

int main() {
    std::vector<cl::Platform> platforms;
    cl::Platform::get(&platforms);
    if(platforms.size() == 0) std::cerr << "in asas\n";
    else std::cout << "compiled normally\n";
}
Run Code Online (Sandbox Code Playgroud)

编辑2:

cl::Platform::getCL_SUCCESS 正常返回。获取平台的过程中没有错误。

还有一些关于我的设置的信息。
GPU:GTX 780Ti
驱动程序:418.56
OpenCL SDK:Nvidia OpenCL / POCL 1.3,带 CPU 和 CUDA 后端
编译器:GCC 8.2.1
操作系统:Arch Linux(内核 5.0.7 x64)

kkm*_*kkm 9

众所周知,NVIDIA 驱动程序与 ASAN 存在冲突。它尝试将内存映射(2)到进程内的固定虚拟内存范围,该范围与ASAN的写保护影子间隙区域一致。鉴于 ASAN 在启动时保留了大约 20TB 的虚拟地址空间,因此其他程序或驱动程序也不太可能发生此类冲突。

\n

ASAN 识别可能在环境变量中设置的某些标志ASAN_OPTIONS。要解决阴影间隙范围冲突,请将该protect_shadow_gap选项设置为0。例如,假设有一个类似 POSIX 的 shell,您可以像这样运行您的程序

\n
$ ASAN_OPTIONS=protect_shadow_gap=0 ./mandelbrot\n
Run Code Online (Sandbox Code Playgroud)\n

可写影子间隙会在 ASAN 下产生额外的性能成本,因为不受保护的间隙需要自己的影子。这就是为什么不建议全局设置此选项(例如,在 shell 启动脚本中的\xc2\xa0g.)。仅对确实需要它的程序启用它。

\n

我几乎可以肯定这是您问题的根本原因。我将 ASAN 与 CUDA 程序一起使用,并且始终需要设置此选项。没有它的 CUDA 报告的故障非常相似:cudaErrorNoDevice尝试选择设备时出错。

\n