mcpField
A
ascendc-mssanitizer

ascendc-mssanitizer

github.com/ascendテスト・品質52118 回インストール25 週間前に更新
リポジトリ

ascendc-mssanitizer について

Ascend C オペレーター開発者向けのメモリ検査スキルです。プロジェクト構成に応じて Python または C++ の手順を選び、mssanitizer を実行して概要と問題分析レポートを作成します。

主な機能

  1. 01構成に応じた検査モードの選択
  2. 02メモリ・競合・初期化・同期の検査
  3. 03C++ テストプログラムの自動ビルド
  4. 04概要とログ分析レポートの作成

活用シーン

  1. 01不正アクセスやメモリリークの調査
  2. 02並列処理のデータ競合と同期問題の確認
  3. 03修正後のオペレーターのメモリ安全性検証

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/ascend/agent-skills --skill ascendc-mssanitizer

インストール後、Claude Code で/ascendc-mssanitizerを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

references/
error_types.md
mssanitizer_usage_guide.md
scripts/
gen_test_script.py
parse_mssanitizer_log.py
run_mssanitizer_geir.sh
run_mssanitizer.sh

詳細

Ascend C 算子 mssanitizer 内存检测分析

系统化检测 Ascend C 算子的内存问题,生成详细分析报告。

概述

mssanitizer(MindStudio Sanitizer)是 CANN 提供的内存正确性检测工具套件,用于检测 AscendC 算子开发中的内存问题,包括:

  • 内存泄漏(Memory Leak)
  • 非法内存访问(Illegal Access)
  • 未初始化内存使用(Uninitialized Memory)
  • 数据竞争(Data Race)
  • 同步问题(Sync Issues)

触发条件

  • 用户需要对 Ascend C 算子进行内存检测
  • 用户请求内存泄漏检测
  • 用户需要验证算子内存安全性
  • 用户提到 "mssanitizer"、"内存检测"、"内存泄漏"、"非法访问" 等关键词

工程类型判断与检测模式选择

关键步骤:在执行检测之前,必须先判断算子工程类型,选择对应的检测模式。

判断逻辑
算子工程目录
├── 存在 op_graph/ 目录? ─── 是 ──→ ops 算子仓 → C++ 模式
├── 存在 op_host/op_api/ 目录? ── 是 ──→ ops 算子仓 → C++ 模式
├── 存在 examples/test_geir_*.cpp? ── 是 ──→ ops 算子仓 → C++ 模式 (GE IR 子模式)
├── 存在 examples/test_aclnn_*.cpp? ── 是 ──→ ops 算子仓 → C++ 模式 (aclnn 子模式)
└── 以上均无 ──→ 自定义算子仓 → Python 模式
检测模式对比
特性Python 模式C++ 模式 (GE IR)C++ 模式 (aclnn)
适用工程自定义算子仓ops 算子仓ops 算子仓
工程特征无 op_graph/、无 examples/有 op_graph/、有 test_geir_*.cpp有 examples/、有 test_aclnn_*.cpp
测试载体Python 脚本(torch_npu 调用)C++ 可执行文件(GE IR 图调用)C++ 可执行文件(aclnn API 调用)
测试脚本gen_test_script.py 生成examples/test_geir_*.cppexamples/test_aclnn_*.cpp
执行脚本run_mssanitizer.shrun_mssanitizer_geir.shrun_mssanitizer_geir.sh
链接库torch_npuascendcl, ge_runner, graph, registerascendcl, opapi, nnopbase
日志前缀memcheck_device_geir_memcheck_device_geir_memcheck_device_
汇总报告mssanitizer_summary_geir_mssanitizer_summary_geir_mssanitizer_summary_
优势覆盖多种 shape/dtype直接调用算子 kernel,更贴近真实执行无需 op_graph,构建更简单
劣势fallback 可能绕过自定义算子需编译 C++ 可执行文件需编译 C++ 可执行文件

注意:run_mssanitizer_geir.sh 脚本已自动支持两种 C++ 子模式,会优先查找 test_geir_*.cpp,找不到时自动回退到 test_aclnn_*.cpp。


工具脚本

本 skill 提供以下脚本,位于 scripts/ 目录:

脚本用途模式
scripts/gen_test_script.py根据算子名称自动生成 Python 测试脚本Python
scripts/run_mssanitizer.shPython 模式:执行全部 5 项检测并生成汇总报告Python
scripts/run_mssanitizer_geir.shC++ 模式:自动构建+检测+生成汇总报告(支持 GE IR 和 aclnn)C++
scripts/parse_mssanitizer_log.py解析 memcheck 日志生成问题分析报告通用

SKILL 根目录: /home/rcz/agent-skills/skills/ascendc-operator-mssanitizer


前置条件

必需的环境变量
环境变量说明获取方式
ASCEND_HOME_PATHCANN 安装路径CANN set_env.sh 设置
LD_LIBRARY_PATH动态库路径包含 CANN lib64
环境激活
source /root/miniconda3/bin/activate cann_env
source /root/miniconda3/envs/cann_env/Ascend/cann-8.5.0/set_env.sh
关键约束(实战经验)
  1. CANN 版本锁定:容器中可能存在多套 CANN(如 cann-8.5 和 cann-9.0),set_env.sh 设置的 ASCEND_HOME_PATH 可能指向错误版本。脚本会显式覆盖为用户指定路径,确保 mssanitizer 使用正确版本。
  2. --check-device-heap 与 --check-cann-heap 互斥:不能同时启用,必须分两次跑 memcheck。
  3. libhccl.so 依赖:mssanitizer 修改 LD_LIBRARY_PATH 后可能丢失 libhccl.so,导致 torch_npu 导入失败。脚本已自动补全 CANN lib64 路径。
  4. 容器兼容性:脚本只使用 grep(非 rg),确保 Docker 容器内可用。
  5. 日志为空 = 无错误:mssanitizer 只在检测到错误时才写入日志文件。日志文件大小为 0 表示该检测项通过,不是工具未运行。

检测工具类型

mssanitizer 提供四种检测工具:

工具命令参数检测内容
内存检测-t memcheck非法内存访问、非法释放、内存泄漏、UB地址越界
竞争检测-t racecheck多核并行竞争条件、数据竞争
未初始化检测-t initcheck未初始化内存读取
同步检测-t synccheck同步错误、同步点问题
常用参数说明
参数说明默认值
-t <tool>指定检测工具memcheck
--leak-check=<yes/no>是否检测内存泄漏no
--check-device-heap=<yes/no>检测 Device 接口泄漏no
--check-cann-heap=<yes/no>检测 AscendCL 接口泄漏(与 device-heap 互斥)no
--log-file=<file>日志输出文件stdout
--log-level=<level>日志级别(warn)warn
--kernel-name=<name>只检测指定名称的 kernelall
--block-id=<id>只检测指定 blockall blocks
--cache-size=<size>单 block 记录缓存大小(MB)100

检测流程

━━━━━━━━━━ 模式 A:Python 模式(自定义算子仓)━━━━━━━━━━

适用于无 op_graph/、无 examples/ 的自定义算子工程。

阶段 1:生成测试脚本

使用 gen_test_script.py 自动生成针对指定算子的测试脚本:

SKILL_DIR="/home/rcz/agent-skills/skills/ascendc-operator-mssanitizer"

python3 "${SKILL_DIR}/scripts/gen_test_script.py" \
    --operator <operator_name> \
    --fallback <fallback_function> \
    --dtypes float16 float32 \
    --output <project>/mssanitizer_test/<operator_name>_mssanitizer_test.py

参数说明:

  • --operator:自定义算子名称(对应 torch.ops.customize.<name>)
  • --fallback:torch.nn.functional 中的回退函数名(如 gelu、relu)。当自定义算子未注册时自动使用,确保 NPU 通路仍会执行并被 mssanitizer 监控
  • --dtypes:要测试的数据类型列表(仅使用算子实际支持的类型)
フェーズ 2:検出の実行
bash "${SKILL_DIR}/scripts/run_mssanitizer.sh" \
    <project>/mssanitizer_test/<operator_name>_mssanitizer_test.py \
    <cann_root>

パラメーターの説明:

  • 第 1 引数:テストスクリプトのパス(フェーズ 1 で生成したもの)
  • 第 2 引数:CANN のインストールルートパス(省略可能。デフォルトでは $ASCEND_HOME_PATH を使用)

このスクリプトは次の処理を自動的に実行します:

  1. memcheck (device-heap) — --check-device-heap=yes --leak-check=yes
  2. memcheck (cann-heap) — --check-cann-heap=yes --leak-check=yes
  3. racecheck — データ競合の検出
  4. initcheck — 未初期化メモリの検出
  5. synccheck — 同期の問題の検出
  6. サマリーレポートの生成 — mssanitizer_summary_<timestamp>.md
  7. memcheck ログの解析 — parse_mssanitizer_log.py を呼び出して詳細な分析レポートを生成
フェーズ 3:ログの個別解析(省略可能)
python3 "${SKILL_DIR}/scripts/parse_mssanitizer_log.py" \
    ./mssanitizer_logs/memcheck_device_<timestamp>.log \
    --output ./mssanitizer_logs/memcheck_analysis_report.md

━━━━━━━━━━ モード B:C++ モード(ops 演算子リポジトリ)━━━━━━━━━━

ops 演算子リポジトリ(ops-nn リポジトリなど)に適しています。プロジェクトディレクトリには op_graph/、examples/、op_host/op_api/ などのディレクトリが含まれます。

特徴
  • C++ 実行可能ファイルを介して演算子を呼び出すため、実際の実行経路に近いです
  • テストソースファイルの種類を自動的に識別します:
    • GE IR サブモード:examples/test_geir_*.cpp を使用し、ascendcl + ge_runner + graph + register にリンクします
    • aclnn サブモード:examples/test_aclnn_*.cpp を使用し、ascendcl + opapi + nnopbase にリンクします
  • C++ 実行可能ファイルがまだビルドされていない場合、自動的にビルドします
  • ログファイルは geir_ プレフィックスで区別されます
ワンステップ実行
SKILL_DIR="/home/rcz/agent-skills/skills/ascendc-operator-mssanitizer"

bash "${SKILL_DIR}/scripts/run_mssanitizer_geir.sh" \
    <project_dir> \
    <cann_root>

パラメーターの説明:

  • 第 1 引数:演算子プロジェクトディレクトリのパス(例:/home/rcz/ops-nn/activation/gelu_quant)
  • 第 2 引数:CANN のインストールルートパス(省略可能。デフォルトでは $ASCEND_HOME_PATH を使用)

スクリプトが自動的に実行する処理:

  1. 演算子プロジェクトの構造を確認し、examples/test_geir_*.cpp または examples/test_aclnn_*.cpp を特定します
  2. テスト実行可能ファイルがまだビルドされていない場合、自動的にビルドします。ソースファイルの種類に応じて、GE IR または aclnn のビルド方法を選択します
  3. 5 項目の検出を順番に実行します(memcheck_device → memcheck_cann → racecheck → initcheck → synccheck)
  4. サマリーレポート geir_mssanitizer_summary_<timestamp>.md を生成します
  5. parse_mssanitizer_log.py を呼び出して詳細な分析レポートを生成します
手動で段階的に実行(省略可能)

より細かく制御する必要がある場合は、手動で実行できます:

# 1. 构建测试可执行文件(首次需要)
cd <project>/mssanitizer_test/build
cmake . && make -j$(nproc)

# 2. 逐项执行检测
MSSAN=<cann_root>/tools/mssanitizer/bin/mssanitizer
LOGDIR=<project>/mssanitizer_logs
TS=$(date +%Y%m%d_%H%M%S)

$MSSAN -t memcheck --check-device-heap=yes --leak-check=yes \
    --log-file=$LOGDIR/geir_memcheck_device_$TS.log \
    -- ./test_geir_<op_name> float

$MSSAN -t memcheck --check-cann-heap=yes --leak-check=yes \
    --log-file=$LOGDIR/geir_memcheck_cann_$TS.log \
    -- ./test_geir_<op_name> float

$MSSAN -t racecheck --log-file=$LOGDIR/geir_racecheck_$TS.log \
    -- ./test_geir_<op_name> float

$MSSAN -t initcheck --log-file=$LOGDIR/geir_initcheck_$TS.log \
    -- ./test_geir_<op_name> float

$MSSAN -t synccheck --log-file=$LOGDIR/geir_synccheck_$TS.log \
    -- ./test_geir_<op_name> float

# 3. 解析日志
python3 ${SKILL_DIR}/scripts/parse_mssanitizer_log.py \
    $LOGDIR/geir_memcheck_device_$TS.log \
    --output $LOGDIR/geir_memcheck_device_analysis_$TS.md

出力ファイル

Python モードの出力

検出の完了後、<project>/mssanitizer_logs/ の下に次のファイルが生成されます:

<project>/mssanitizer_logs/
├── memcheck_device_<ts>.log           # memcheck device-heap 原始日志
├── memcheck_device_report_<ts>.json   # memcheck device-heap 测试结果
├── memcheck_device_analysis_<ts>.md   # memcheck device-heap 解析报告
├── memcheck_cann_<ts>.log             # memcheck cann-heap 原始日志
├── memcheck_cann_report_<ts>.json
├── memcheck_cann_analysis_<ts>.md
├── racecheck_<ts>.log
├── racecheck_report_<ts>.json
├── initcheck_<ts>.log
├── initcheck_report_<ts>.json
├── synccheck_<ts>.log
├── synccheck_report_<ts>.json
└── mssanitizer_summary_<ts>.md        # 汇总报告
GE IR モードの出力

検出の完了後、<project>/mssanitizer_logs/ の下に次のファイルが生成されます:

<project>/mssanitizer_logs/
├── geir_memcheck_device_<ts>.log      # memcheck device-heap 原始日志
├── geir_memcheck_cann_<ts>.log        # memcheck cann-heap 原始日志
├── geir_racecheck_<ts>.log
├── geir_initcheck_<ts>.log
├── geir_synccheck_<ts>.log
└── geir_mssanitizer_summary_<ts>.md   # 汇总报告(含解析)

注意:ログファイルのサイズが 0 の場合、その検出項目は合格しており、エラーは検出されていません。mssanitizer はエラーを検出した場合にのみログ内容を書き込みます。


段階的な検出戦略

CANN ソフトウェアスタックの構造に基づき、memcheck を 2 段階で実行してメモリリークの発生箇所を特定します:

┌─────────────────────────────────────┐
│         用户代码(Host 侧)          │
├─────────────────────────────────────┤
│      AscendCL 接口(CANN API)       │
├─────────────────────────────────────┤
│     Device 接口(驱动层接口)         │
└─────────────────────────────────────┘

ステップ 1:Device インターフェイスのリークを検出

mssanitizer -t memcheck --check-device-heap=yes --leak-check=yes -- python3 test.py
# 或 GE IR 模式:
mssanitizer -t memcheck --check-device-heap=yes --leak-check=yes -- ./test_geir_op float
  • リークが出力されない場合 → リークは Device 側のアプリケーションで発生しています
  • リークが出力された場合 → ステップ 2 に進みます

ステップ 2:AscendCL インターフェイスのリークを検出

mssanitizer -t memcheck --check-cann-heap=yes --leak-check=yes -- python3 test.py
# 或 GE IR 模式:
mssanitizer -t memcheck --check-cann-heap=yes --leak-check=yes -- ./test_geir_op float

エラーの種類と重大度

重大度の分類
重大度エラーの種類対応の優先度
🔴 重大illegal_write, illegal_read, illegal_free直ちに修正
🟡 中程度memory_leak早急に修正
🟢 軽微未初期化メモリの使用修正を推奨
ログの主要フィールドの説明
フィールド説明例
at 0x... on GMグローバルメモリアドレス0x12c000000010
in block on device Nデバイスと block の情報device 0
serialNo:Nコード位置の特定に使用する命令シーケンス番号serialNo:22
size Nアクセスしたバイト数size 8
問題を特定するためのヒント
  1. serialNo を使用した特定:serialNo はコンパイル後の命令シーケンス番号に対応します。コンパイルオプションに -g を追加すると、ソースコード上の位置を取得できます
  2. アドレス分析:GM アドレスは、メモリレイアウトや範囲外アクセスの分析に使用できます
  3. サイズ分析:アクセスサイズは、データ型や操作の種類を判断するのに役立ちます
  4. illegal_free の関連分析:illegal_free が illegal_write と併発する場合、通常は範囲外書き込みによってメモリ管理構造が破損しています。まず illegal_write を修正してください

よくある問題のチェックリスト

1. DataCopy のパラメーターエラー

症状:illegal write/read エラー

確認手順:

  1. DataCopy の 3 番目のパラメーターが正しいか確認します
  2. 要素数の計算が正しいか確認します(注意:パラメーターはバイト数ではなく要素数です)
  3. コピー元/コピー先のアドレスが範囲外でないか確認します

典型的なエラー:

// 错误:乘以 sizeof(T) 或其他系数
DataCopy(xLocal, xGlobal, totalLength * sizeof(T));  // ❌
DataCopy(xLocal, xGlobal, totalLength * 2);           // ❌

// 正确:直接使用元素数量
DataCopy(xLocal, xGlobal, totalLength);               // ✓
2. メモリの割り当てと解放が対応していない

症状:memory leak エラー

確認手順:

  1. すべての AllocTensor に対応する FreeTensor があるか確認します
  2. EnQue/DeQue が対になって使用されているか確認します
  3. pipe.InitBuffer のバッファー管理を確認します

典型的なエラー:

// 错误:忘记释放
LocalTensor<T> xLocal = xQueue.AllocTensor<T>();
// ... 使用 xLocal
// 缺少 xQueue.FreeTensor(xLocal);  // ❌

// 正确:配对使用
LocalTensor<T> xLocal = xQueue.AllocTensor<T>();
// ... 使用 xLocal
xQueue.FreeTensor(xLocal);  // ✓
3. UB バッファーのサイズ不足

症状:UB address out of bounds エラー

確認手順:

  1. pipe.InitBuffer で割り当てたサイズが十分か確認します
  2. データ型のサイズ計算が正しいか確認します
  3. 32 バイトのアラインメントが必要か確認します

典型的なエラー:

// 错误:缓冲区大小不足
pipe.InitBuffer(tmpBuffer, totalSize);  // ❌ 未考虑临时空间需求

// 正确:根据算子需求分配足够空间
pipe.InitBuffer(tmpBuffer, totalSize * sizeof(T) + EXTRA_SPACE);  // ✓

トラブルシューティング

問題: mssanitizer が見つからない

確認項目:

  • ASCEND_HOME_PATH が正しい CANN ルートパスを指していることを確認します
  • CANN のバージョンが mssanitizer をサポートしていることを確認します(8.0+)
  • コンテナー内に複数の CANN が存在する場合があります。cann_root パラメーターを明示的に渡してください
問題: torch_npu のインポートに失敗する (libhccl.so)

原因: mssanitizer の起動時に LD_LIBRARY_PATH が変更され、CANN の lib64 パスが失われます

解決策: run_mssanitizer.sh は CANN の lib64 パスを LD_LIBRARY_PATH の先頭に自動的に追加します。それでも失敗する場合は、手動で実行してください:

export LD_LIBRARY_PATH=<cann_root>/lib64:$LD_LIBRARY_PATH
問題: CANNOT enable both --check-device-heap and --check-cann-heap

原因: この 2 つのオプションは同時に指定できません

解決策: memcheck を 2 回に分けて実行してください(run_mssanitizer.sh/run_mssanitizer_geir.sh ではすでに自動的に処理されます)

問題: ログに <unknown>:0 と表示される

原因: 演算子のコンパイル時に -g デバッグオプションが追加されていません

解決策: 演算子を再コンパイルし、-g -O0 オプションを追加してください

問題: ログファイルのサイズが 0

原因: mssanitizer はエラーを検出した場合にのみログファイルに書き込みます

解決策: ログが 0 バイトの場合、その検出項目は合格しているため、対応は不要です。mssanitizer の内部ログ(mindstudio_sanitizer_log/)で、ツールが正常に動作していることを確認できます。

问题: C++ 模式构建失败

检查项:

  • 确认 examples/ 目录下存在 test_geir_*.cpp 或 test_aclnn_*.cpp
  • GE IR 模式:确认 op_graph/ 目录存在且包含算子 proto 头文件
  • aclnn 模式:确认 CANN 的 lib64/ 和 aarch64-linux/lib64/ 下有 libopapi.so 和 libnnopbase.so
  • 确认 CANN 环境已正确激活(ASCEND_HOME_PATH、LD_LIBRARY_PATH)
  • 检查 CMake 输出中的编译错误
  • 如链接 libopapi.so 失败,检查 CANN 架构子目录路径(aarch64-linux/lib64)
问题: 未检测到错误但程序失败

检查项:

  • 尝试其他 mssanitizer 工具(racecheck、initcheck)
  • 检查逻辑错误
  • 使用其他调试工具

注意事项

  1. 性能影响:mssanitizer 会显著降低程序运行速度(可能慢 10-100 倍),仅用于调试
  2. 内存开销:检测过程需要额外内存记录分配信息,可能需要更大的内存
  3. 多次运行:某些问题可能不是每次都复现,建议多次运行检测
  4. 模式选择:ops 算子仓优先使用 C++ 模式(脚本自动识别 GE IR / aclnn),能直接调用算子 kernel,检测结果更准确

最佳实践

  1. 添加调试信息: 编译时添加 -g -O0 以获取精确的代码位置
  2. 执行所有检测模式: 运行全部检测模式(脚本已默认执行全部 5 项)
  3. 按优先级修复: 先解决非法访问问题,再处理内存泄漏
  4. 重新验证: 修复后重新运行 mssanitizer 确认问题已解决
  5. 定期检测: 在算子开发完成后、修改内存相关代码后、提交代码前进行检测
  6. 选择正确模式: ops 算子仓用 C++ 模式(脚本自动识别 GE IR / aclnn),自定义算子用 Python 模式

相关文档

コメント