已关闭
[Bug-Report|缺陷反馈][工具检测] Matmul `GetVecTensor()` 设备侧丢失 tensor 长度,MSTX 打点上报 `size=0`,导致 mssanitizer memcheck 误报 62 条 #1783
Goldfish_of_Siris创建于  8 天前关闭于  1 天前
Goldfish_of_Siris
Goldfish_of_Siris
8 天前 创建

Thanks for sending an issue! Please fill in the following template to help quickly solve your problem.

Describe the current behavior / 问题描述 (Mandatory / 必填)

出错位置:include/adv_api/matmul/matmul_client.h:1946 的 GetVecTensor()

        tbufOutTmp.bufferAddr = addr;
#if ASCENDC_CPU_DEBUG                 // ← 问题在这:dataLen(及 absAddr)只在调试宏内赋值
        tbufOutTmp.dataLen = size * sizeof(T);
        tbufOutTmp.absAddr = reinterpret_cast<uint8_t*>(addr);
#endif
        cLocal.SetAddr(tbufOutTmp);   // 设备编译时 dataLen 未赋值 ⇒ GetSize()==0(长度丢失)
        return cLocal;

为什么会导致误报:该 UB 句柄随后作为 DataCopy(dst=L1, src=UB, {1,1,0,0}, …) 的 src 使用,
DataCopy 内部打 MSTX 打点(impl/basic_api/mstx_local_tensor_info.h:1744 GetMstxDataCopyInfo),
打点里的 size 唯一来源就是 LocalTensor::GetSize()(= address_.dataLen / sizeof(T))。
长度丢失 ⇒ 记录变成 src:(addr:0x800,size:0,space:UB);而 mssanitizer 的 memcheck 把"本条记录描述的 tensor"
当作该指令的合法访问区间(长度 size * dataBits / 8)⇒ 长度 0 = 空区间 ⇒ 合法 UB 访问被判越界。

影响面:凡 A/B 在 UB 的 Matmul(SetTensorA/SetTensorB(LocalTensor),KFC client 路径)都会上报 size=0;
本实例误报 62 条(地址 0x800~0xF80 全部落在合法 vecout 缓冲区 UB 0x800–0xFFF 内)。

修复方式(建议)

把 dataLen 的赋值移出 #if ASCENDC_CPU_DEBUG(absAddr 仍留在宏内,仅 CPU 调试需要):

--- a/include/adv_api/matmul/matmul_client.h
+++ b/include/adv_api/matmul/matmul_client.h
@@ -1949,12 +1949,12 @@
         tbufOutTmp.bufferAddr = addr;
-#if ASCENDC_CPU_DEBUG
         if (IsTypeOneOfV<T, fp4x2_e1m2_t, fp4x2_e2m1_t>) {
             tbufOutTmp.dataLen = size / AscendC::Impl::FP4_TWO;
         } else {
             tbufOutTmp.dataLen = size * sizeof(T);
         }
+#if ASCENDC_CPU_DEBUG
         tbufOutTmp.absAddr = reinterpret_cast<uint8_t*>(addr);
 #endif
         cLocal.SetAddr(tbufOutTmp);

补丁文件:patch_GetVecTensor_dataLen.diff。
⚠️ asc-devkit 仓源码不参与编译,实际编译取的是 CANN 包内同源副本
(<CANN>/asc/include/adv_api/matmul/matmul_client.h,与仓内文件内容一致),验证时改的是该副本。

Environment / 环境信息 (Mandatory / 必填)

Ascend950PR / --npu-arch=dav-3510;CANN 9.1.0(730 包);mssanitizer 26.0.0(插桩版);
样例 <asc-devkit>/examples/01_simd_cpp_api/04_advanced_api/00_matmul/matmul_vecout(half / ND,A 在 UB)。

Steps to reproduce the issue / 重现步骤 (Mandatory / 必填)

source <CANN>/set_env.sh
export ASCFLAGS="-g --cce-enable-sanitizer" TMPDIR=/tmp/build_tmp ASCEND_RT_VISIBLE_DEVICES=<free_npu>
cd <样例目录> && mkdir -p build && cd build
cmake -DCMAKE_ASC_ARCHITECTURES=dav-3510 -DCMAKE_ASC_LINK_FLAGS=--cce-enable-sanitizer .. && make -j$(nproc)

# 1) 功能正常(说明不是算子算错)
python3 ../scripts/gen_data.py && ./demo && python3 ../scripts/verify_result.py output/output.bin output/golden.bin   # test pass!

# 2) 内存检测:出现 62 条误报
mssanitizer -t memcheck --log-level=error -- ./demo

# 3) 打开记录流:看到 UB 侧 size=0(关键证据)
MSSANITIZER_ENABLE_DEBUG_LOG=1 INJ_LOG_LEVEL=1 mssanitizer -t memcheck --log-level=error -- ./demo
grep "space:L1" mindstudio_sanitizer_log/mssanitizer_*.log | head

Describe the expected behavior / 预期结果 (Mandatory / 必填)

记录中 UB 侧 src.size memcheck
实际(基线) 0(31 条记录全为 0) 62 条:31×illegal read of size 32 + 31×illegal read of size 30,地址 0x800~0xF80 全在 vecout(UB 0x800–0xFFF)内
预期 1024(A tile 2048 B ÷ 2 B) No error detected

打上述补丁后实测:src.size 0 → 1024,memcheck 62 → 0(No error detected),纯跑仍 test pass!(3/3)。

  1. 告警详情:mssanitizer -t memcheck … 的 stdout —— 告警块含 at 0x… on UB、pc current 0x6c88、
    serialNo、源码栈(本实例指向样例 matmul_vecout.asc:150,即 IterateAll)。
    → 附件 日志/基线_memcheck_62条.txt(62 条)、日志/修复后_memcheck_0条.txt(No error detected)

  2. MSTX 记录流:加 MSSANITIZER_ENABLE_DEBUG_LOG=1 INJ_LOG_LEVEL=1 后写入
    build/mindstudio_sanitizer_log/mssanitizer_<时间戳>_<pid>.log,每行前缀 [checker.cpp:515] MSTX_STUB, …;
    grep "space:L1" 即本条问题的记录:dst:(addr:0x0,size:8192,space:L1) , src:(addr:0x800,size:0,space:UB)。
    → 附件 日志/MSTX记录流_基线_全量.log、日志/MSTX记录流_修复后_全量.log,
    以及精简对比 日志/记录片段_修复前_src.size=0.txt / 日志/记录片段_修复后_src.size=1024.txt

  3. pc → 源码(定位调用链,推荐):-g 编译产物中 .aicore_binary 段即设备 ELF(检测工具只给 2 帧,用它能拿到完整内联栈):

    llvm-objcopy --dump-section .aicore_binary=dev.bin CMakeFiles/demo.dir/matmul_vecout.asc.o
    llvm-addr2line -e dev.bin -f -C -i 0x6c88
    # CopyUbAToL1ForND(matmul_client.h:2325) ← CopyUB2L1ND2NZ(:2083) ← CopyND2NZOnTheFly(:2121)
    #   ← CopyND2NZOnTheFlyWithTail(:2150) ← DataCopy(kernel_operator_data_copy_intf_impl.h:997)
    

    → 附件 分析数据/addr2line_pc0x6c88_内联栈.txt(原始输出)

  4. 其余附件:源码片段/(修复前 / 修复后 / 同类隐患)、patch_GetVecTensor_dataLen.diff、
    复现与验证.sh(一键复现 + 验证,末尾自动还原 CANN 源文件)、附件说明.txt(文件清单)

    227_matmul_vecout_mssanitizer.zip

Special notes for this issue/备注 (Optional / 选填)

likedislike
Kkong0808成员
6 天前 将 zhengchao0613 设为负责人
zc1110
zc1110成员
6 天前 评论:

您好,感谢你报告这个问题!当前正在本地复现和解决中

likedislike
zc1110zc1110成员
2 天前 关联了pull request:fix GetVecTensor size get
zc1110
zc1110成员
1 天前 评论:

您好,当前修改PR已合入,https://gitcode.com/cann/asc-devkit/pull/6448

likedislike
zc1110zc1110成员
1 天前 issue状态由 待办的 改变为 已解决
zc1110zc1110成员
1 天前 关闭了 issue
CANN-robotCANN-robot成员
1 天前 添加了label:resolved