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

时间:2019-04-18 17:02:39

标签: c++ debugging opencl address-sanitizer

我正在调试崩溃的OpenCL应用程序问题。因此,我启用了asan来确定问题的出处。但是后来我发现,通过打开asan并重新编译,我的应用程序找不到任何OpenCL设备。 (从字面上将-fsanitize=address添加到编译器选项使我的程序无法使用OpenCL)。 经过进一步的测试,我发现内存清理程序可以与OenCL一起使用。

为什么会这样?如何在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";
}

编辑2:

cl::Platform::get通常返回CL_SUCCESS。获取平台的过程中没有错误。

有关我的设置的一些信息。
GPU:GTX 780Ti
司机:418.56
OpenCL SDK:具有CPU和CUDA后端的Nvidia OpenCL / POCL 1.3
编译器:GCC 8.2.1
操作系统:Arch Linux(Kernel 5.0.7 x64)

1 个答案:

答案 0 :(得分:2)

已知 NVIDIA 驱动程序与 ASAN 冲突。它试图将 mmap(2) 内存放入进程内的固定虚拟内存范围内,这与 ASAN 的 write-protected shadow gap region 不谋而合。鉴于 ASAN 在启动时保留了大约 20TB 的虚拟地址空间,因此与其他程序或驱动程序发生冲突的可能性也不大。

ASAN 识别某些 flags that may be set in the ASAN_OPTIONS 环境变量。要解决阴影间隙范围冲突,请将 protect_shadow_gap 选项设置为 0。例如,假设一个类似 POSIX 的 shell,你可以像

一样运行你的程序
$ ASAN_OPTIONS=protect_shadow_gap=0 ./mandelbrot

可写影子间隙在 ASAN 下会产生额外的性能成本,因为未受保护的间隙 requires its own shadowing。这就是为什么不建议全局设置此选项的原因(例如,在您的 shell 启动脚本中)。仅对实际上需要它的程序启用它。

我几乎可以肯定这是您问题的根本原因。我将 ASAN 与 CUDA 程序一起使用,并且始终需要设置此选项。没有它的 CUDA 报告的失败非常相似:cudaErrorNoDevice error when I try to select a device.