检测CANN软件栈的内存
针对用户程序调用CANN软件栈接口可能出现的内存异常操作场景,msSanitizer检测工具提供了Device相关接口和AscendCL相关接口的内存检测能力,方便用户对程序内存异常操作位置的排查和定位。
内存泄漏检测使用原理
当npu-smi info命令查询到的设备内存不断增大时,可使用本工具进行内存泄漏定位定界,若AscendCL系列接口泄漏可支持定位到代码行。
如图1所示,CANN软件栈内存操作接口包含两个层级,向下使用驱动侧提供的device侧接口,向上提供了AscendCL系列接口供用户代码调用。
内存泄漏定位可分为以下步骤:
- 使能device系列接口泄漏检测,判断内存泄漏是否发生在host侧。若没有,则定界到device侧的应用出现泄漏;若有,则通过下一个步骤判断AscendCL接口调用是否发生泄漏;
- 使能AscendCL系列接口泄漏检测,判断用户代码调用AscendCL接口是否存在泄漏。若没有,则定界为非AscendCL接口调用问题;如果出现泄漏,则通过下一步定位到具体代码行;
- 使用msSanitizer检测工具中提供的新接口,对头文件重新编译,再用检测工具拉起检测程序,可定位到未释放内存的分配函数所对应的文件名与代码行号。新接口的详细说明请参见msSanitizer对外接口使用说明。
排查步骤
- 参考使用前准备完成相关环境变量配置。
- 定界是否为host侧泄漏。
- 使用msSanitizer检测工具拉起待检测程序,命令示例如下:
mssanitizer --check-device-heap=yes --leak-check=yes ./add_custom_npu
待检测程序(以add_custom_npu为例)所在路径可配置为绝对路径或相对路径,请根据实际环境配置。
- 若无异常输出则说明检测程序运行成功,且host侧不存在内存泄漏情况;若输出如下错误说明host侧的应用出现了内存泄漏。
- 使用msSanitizer检测工具拉起待检测程序,命令示例如下:
- 定界是否为AscendCL接口调用导致泄漏。
- 使用msSanitizer检测工具拉起待检测程序,命令示例如下:
mssanitizer --check-cann-heap=yes --leak-check=yes ./add_custom_npu
- 若无异常输出则说明检测程序运行成功,且AscendCL接口调用不存在内存泄漏情况;若输出如下错误说明AscendCL接口调用出现了内存泄漏。
- 使用msSanitizer检测工具拉起待检测程序,命令示例如下:
- 通过msSanitizer检测工具中提供的接口定位发生泄漏的代码文件和代码行。
- msSanitizer检测工具提供了msSanitizer API头文件“acl.h”,其路径为 ${INSTALL_DIR}/tools/mssanitizer/include/acl,对应的动态库路径为 ${INSTALL_DIR}/tools/mssanitizer/lib64/libascend_acl_hook.so。
- 将用户代码中原有的“acl/acl.h”头文件替换为工具中提供的头文件“acl/acl.h”。
- 将动态库libascend_acl_hook.so链接至用户的应用工程中,并重新编译应用工程。
- 重新使用msSanitizer检测工具拉起程序,命令示例如下:
mssanitizer --check-cann-heap=yes --leak-check=yes ./add_custom_npu
以下输出结果表明在调用应用程序main.cpp的第55行存在一次内存分配但未释放,至此可定位到内存泄漏的原因。
1 2 3 4 5 6
====== ERROR: LeakCheck: detected memory leaks ====== Direct leak of 32768 byte(s) ====== at 0x124080024000 on GM allocated in main.cpp:55 (serialNo:0) ====== SUMMARY: 32768 byte(s) leaked in 1 allocation(s)
父主题: 典型案例