我正在调试崩溃的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)
答案 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.