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

标签 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";
}
编辑2:cl::Platform::get CL_SUCCESS 正常返回。获取平台的过程中没有错误。
还有一些关于我的设置的信息。
显卡:GTX 780Ti
司机:418.56
OpenCL SDK:Nvidia OpenCL/POCL 1.3 带 CPU 和 CUDA 后端
编译器:GCC 8.2.1
操作系统:Arch Linux(内核 5.0.7 x64)

最佳答案

已知 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 下产生额外的性能成本,因为未 protected 间隙 requires its own shadowing .这就是为什么不建议全局设置此选项的原因(例如,在您的 shell 启动脚本中)。仅为实际上需要它的程序启用它。
我几乎可以肯定这是您问题的根本原因。我将 ASAN 与 CUDA 程序一起使用,并且始终需要设置此选项。没有它的 CUDA 报告的故障非常相似:cudaErrorNoDevice尝试选择设备时出错。

关于c++ - 使用 Address Sanitizer 编译主机应用程序时可使用 OpenCL,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55750700/

相关文章:

c++ - QObjects 移入 QThreads 后信号不再工作

c++ - 通过重载 < 对自定义对象的 vector 进行排序

java - 将 MigLayout Debug模式绑定(bind)到应用程序的日志记录级别?

Python:当我的模块返回 "Ellipsis"时,这意味着什么?

php - 这是一个真正的挑战 : why does PHP call shutdown function before sessions are written?

clGetProgramBuildInfo 不打印构建日志

c++ - Boost::algorithms 是否包含在标准库中?

c++ - 如何在更改编译器/操作系统方面使 C++ 代码健壮

parameters - 在开放的 CL 中将结构数组传递给内核

c++ - OpenCL 的 clEnqueueReadBufferRect 适用于 int 但不适用于 double 数据类型