news 2026/9/19 21:09:08

CANN Runtime Profiling 错误码 EK9999(System_Terminated)深度解析:错误语义、产生场景与日志定位指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
CANN Runtime Profiling 错误码 EK9999(System_Terminated)深度解析:错误语义、产生场景与日志定位指南

CANN Runtime Profiling 错误码 EK9999(System_Terminated)深度解析:错误语义、产生场景与日志定位指南

【免费下载链接】runtime本项目提供CANN运行时组件和维测功能组件。项目地址: https://gitcode.com/cann/runtime

导读

EK9999(System_Terminated)是 CANN/runtime 仓库中 Profiling(性能采集)子系统用于兜底的“未知内部错误”错误码,其对外呈现为一句高度抽象的提示An unknown error occurred. Please check the log.。本文以 EK9999-System_Terminated.md 为主线,结合 error_code.json 中 EK9999 的注册定义,以及 msprof 采集链路中所有上报 EK9999 的真实代码点位,说明该错误码的定位方式、常见触发场景与日志排查路径,帮助你快速建立“看到 EK9999 后下一步该做什么”的完整思路。

EK9999 错误码的定位:Profiling 子系统的“内部错误兜底码”

官方错误码表中的地位

在 CANN/runtime 的 Profiling 错误码族(EK前缀)中,EK9999 是专门留给“系统/内部未知错误”的兜底码。其语义在官方文档中表述为:

  • 英文文档:EK9999-System_Terminated.md
  • 中文文档:EK9999-System_Terminated.md

官方给出的“错误信息(Symptom)”为:

An unknown error occurred. Please check the log.

即:错误本身未知,需要借助日志进一步定位。中文版文档的“解决方法”进一步说明:内部错误,请根据日志进一步定位问题,或联系华为工程师

错误码注册表:error_code.json 中的定义

该错误码并非仅在文档中存在,而是注册在 CANN/runtime 的错误码管理配置文件 src/dfx/error_manager/error_code.json 中(第 1315~1325 行附近)。其注册结构如下:

{ "errClass": "Profiling Errors", "errTitle": "System_Terminated", "ErrCode": "EK9999", "ErrMessage": "An unknown error occurred. Please check the log.", "Arglist": "", "suggestion": { "Possible Cause": "N/A", "Solution": "N/A" } }

从这份注册表可以读出三个关键信息:

  1. 错误归类errClassProfiling Errors,与 EK0001~EK0204 等错误码同属 Profiling 错误族;
  2. 无参数化占位Arglist为空字符串,说明 EK9999 的对外信息中不含任何可动态填充的参数,用户侧永远只会看到那句固定的提示;
  3. 无标准建议Possible CauseSolution均为N/A,与文档中 "Solution: N/A" 完全对应。这从机制上确认了:EK9999 不是一个可以给出通用解决方案的错误码,其解决路径只能依赖日志

命名约定:K 前缀的含义

在 CANN/runtime 的错误码体系(详见 macro-selection-guide.md)中,错误码第一个字母代表错误所属模块域:

前缀字母模块域典型码位
E执行错误(Execution)EE9999(Runtime 内部错误)
KProfilingEK9999
LDriverEL9999
ZNPU 公共 / TBEEZ9999
E2FE(前端编译)E29999
E3AICPUE39999
IHCCLEI9999

Runtime 核心代码 base_info.hpp 中集中定义了这些“内部兜底码”常量,其中与本文直接相关的一行是:

static constexpr const char_t* RT_PROFILE_INNER_ERROR = "EK9999";

可以看到,EK9999 在 Runtime 侧被显式命名为“Profiling 内部错误”RT_PROFILE_INNER_ERROR),与 EE9999(Runtime 内部错误)、EZ9999(NPU 公共内部错误)、E29999(FE 内部错误)等并列。这进一步证实:只要 Profiling 链路中出现了未能映射到具体 EK 错误码的未知失败,统一收敛到 EK9999。

EK9999 的典型产生场景:来自 msprof 采集链路的真实证据

EK9999 并非只在极端情况下出现。从源码看,msprof 采集链路中有大量具体失败场景最终以 EK9999 上报。这些场景主要分布在 src/dfx/msprof/collector/dvvp 下的任务管理、引擎回调、作业包装器(job wrapper)与适配层中。

场景一:采集任务管理与生命周期(prof_task / prof_manager)

任务创建与设备初始化阶段是 EK9999 的高发区,参见 prof_task.cpp:

  • 生成info.json失败时上报"EK9999", "Failed to generate info.json."
  • 设备已在采集中(重复启动)时上报"EK9999", "Device %s is already running profiling, skip the device."
  • 设备 init 失败时上报"EK9999", "Device %s init failed, ret: %d."
  • 设备 start 失败时上报"EK9999", "Device %s start failed, ret: %d."

任务调度侧 prof_manager.cpp 也有对应场景:

  • 设备已在采集中:"EK9999", "Device is already in profiling, device id: %s, job id: %s."
  • 启动采集任务失败:"EK9999", "Failed to launch profiling task, device id: %s, job id: %s."
  • 处理采集任务失败:"EK9999", "Failed to handle profiling task, device id: %s, job id: %s."
  • 解析采样配置失败:"EK9999", "Failed to parse sample config."
  • 生成sample.json失败:"EK9999", "Failed to create sample.json."
  • 参数检查失败:"EK9999", "Failed to check profiling params."

要点:这些点位说明,重复对同一设备启动采集、设备初始化/启动异常、配置解析失败等,都会收敛到 EK9999 这个兜底码。

场景二:引擎回调与订阅管理(prof_acl_mgr)

引擎管理与订阅管理是另一个 EK9999 密集区域,参见 prof_acl_mgr.cpp:

  • 回调 init/start/stop/finalize 失败:如"EK9999", "Failed to callback init.""EK9999", "Failed to callback start on device %u.""EK9999", "Failed to callback stop on device %u.""EK9999", "Failed to callback finalize."
  • 订阅管理失败:如"EK9999", "%s has not been subscribed.""EK9999", "Failed to close subscribe fd %d."、重复订阅时"EK9999", "Failed to pass subscribe check, key %s has been subscribed"
  • 工具链兼容性场景:"EK9999", "Params created by msprof in oam-tools can not be analyzed by ..."(提示 msprof 工具产生的参数与当前分析组件不兼容)。

场景三:作业包装器与宿主进程(prof_host_job / prof_perf_job)

Host 侧采集作业管理同样会收敛到 EK9999,参见 prof_host_job.cpp 与 prof_perf_job.cpp:

  • ProfHostService初始化/启动/停止失败:如"EK9999", "Failed Init profHostService_""EK9999", "Failed Start profHostService_"
  • 宿主采集进程异常:如"EK9999", "Failed to kill process %s, ret=%d, exitCode=%d""EK9999", "Failed to wait process %d, ret=%d, exitCode=%d"、pid 无效时"EK9999", "ProfHostCcaMsJob pid: %d is invalid."
  • perf 采集文件打开失败:"EK9999", "Failed to open %s, dev_id=%d"

场景四:msproftx 打点与适配层

  • msprof_tx_manager.cpp 中 msproftx 打点数据上报失败:"EK9999", "Failed to report msproftx stamp data."
  • msprofiler_impl.cpp 中回调 init 失败:"EK9999", "Failed to callback init."

EK9999 的上报机制:MSPROF_INNER_ERROR

上述所有点位都通过宏MSPROF_INNER_ERROR上报错误,该宏在 msprof_error_manager.h 中定义:

#define MSPROF_INPUT_ERROR(errorCode, key, value) \ Analysis::Dvvp::MsprofErrMgr::MsprofErrorManager::instance()->ReportErrorMessage(errorCode, key, value) #define MSPROF_ENV_ERROR MSPROF_INPUT_ERROR #define MSPROF_INNER_ERROR REPORT_INNER_ERR_MSG #define MSPROF_CALL_ERROR MSPROF_INNER_ERROR

MSPROF_INNER_ERROR展开为REPORT_INNER_ERR_MSG,即通过MsprofErrorManager::ReportErrorMessage将“错误码 + 具体错误文本”送入错误上报通道。这正是 EK9999 区别于其他 EK 错误码的地方:虽然用户侧最终看到的都是同一句An unknown error occurred. Please check the log.,但伴随上报的日志中会携带上述源码中看到的具体失败原因文本(如Failed to callback start on device 0.)。因此,“看日志”不是一句空话——日志中记录的往往是比 EK9999 本身更有价值的精确信息。

排查路径:拿到 EK9999 后如何继续定位

由于官方文档明确 "Solution: N/A",EK9999 的定位只能依赖日志,建议按以下顺序排查:

第一步:确认错误码来源模块

  • 先确认报错上下文是否与 Profiling 相关:EK 前缀 = Profiling,即 msprof 采集链路;
  • 若同时出现其他前缀错误码(如 EE/LZ/EL),按错误码表(Profiling-Errors.md)与 macro-selection-guide.md 中的模块域映射,判断是否由底层模块失败传导而来。

第二步:定位伴随的具体错误日志

  • 检索日志中 EK9999 前后的上下文字段,对照上文列出的真实上报点位,确认属于哪一类失败:
    • 任务/设备管理类 → prof_task.cpp、prof_manager.cpp;
    • 引擎回调/订阅类 → prof_acl_mgr.cpp;
    • 宿主/采集进程类 → prof_host_job.cpp、prof_perf_job.cpp;
    • 打点上报类 → msprof_tx_manager.cpp。
  • 例如日志中出现Failed to launch profiling task, device id: 0, job id: xxx,则对应 prof_manager.cpp 中启动采集任务失败的路径,应围绕设备状态与任务并发冲突排查;若出现Device 0 is already running profiling,则应检查是否有重复的采集任务在并发执行。

第三步:结合具体失败原因处理

常见原因与对应处置参考如下:

日志中的失败文本(示例)常见诱因处置方向
Device %s is already running profiling同一设备被重复启动采集等待上一轮采集结束,或复用同一任务句柄,避免并发重复启动
Device %s init/start failed, ret: %d设备侧采集初始化/启动失败检查设备状态、驱动与资源可用性,结合ret值进一步定位
Failed to parse sample config/Failed to check profiling params采集配置非法核对 prof 配置文件的参数格式与取值范围
Failed to callback start/stop on device %u引擎回调异常检查对应采集引擎是否正常加载,必要时重新初始化
Failed to generate info.json/Failed to create sample.json结果文件目录不可写或磁盘空间不足检查采集输出目录权限与剩余空间(Profiling flush 至少需要一定存储空间,参见 EK0204 的 20MB 提示)
Failed to kill/wait process %s, ret=%dHost 侧采集子进程异常退出检查进程存活状态与退出码,必要时清理残留进程后重试

需要说明:上表“常见诱因/处置方向”属于基于源码上报文本的合理推断,实际根因需结合现场日志(日志级别、设备侧信息)进一步确认;若上述步骤无法定位,按中文文档建议联系华为工程师并提供日志。

第四步:无法定位时

  • 保留完整日志(Host 侧与设备侧)与采集配置;
  • 按 Profiling-Errors.md 的目录索引,确认 EK9999 是否与其他 EK 错误码(EK0001~EK0204)并列出现,缩小问题范围;
  • 将日志提供给技术支持时,重点提供 EK9999 出现前、后的上下文,以及ret/exitCode/fd等数值字段。

延伸理解:EK9999 与相邻兜底错误码的分工

EK9999 不是仓库中唯一的“未知错误兜底码”。从 base_info.hpp 可见,Runtime 为各模块域都定义了对应的内部兜底码:

常量错误码模块域
RT_INNER_ERROREE9999Runtime 执行域
RT_PROFILE_INNER_ERROREK9999Profiling 域
RT_DRV_INNER_ERROREL9999Driver 域
RT_NPU_COMMON_INNER_ERROREZ9999NPU 公共/TBE
RT_FE_INNER_ERRORE29999FE 前端
RT_AICPU_INNER_ERRORE39999AICPU
RT_HCCL_INNER_ERROREI9999HCCL

理解这一“一域一兜底码”的分工后,排查时的第一步就非常明确:看到 EK9999,优先把注意力收敛到 Profiling 采集链路(msprof)的日志,而非全量 Runtime 日志。这也是官方只给出“检查日志”这一条指引、却未提供通用修复步骤的根本原因——EK9999 本身只是一个“入口错误码”,真正的答案藏在它背后那句具体的失败文本里。

总结

  • EK9999 是什么:Profiling 域的“未知内部错误”兜底码,注册于 error_code.json,对外固定输出An unknown error occurred. Please check the log.,无参数化信息、无通用解决方案(Solution: N/A)。
  • 从哪来:msprof 采集链路中所有未映射到具体 EK 码的失败,包括任务创建与调度、设备重复采集、引擎回调、订阅管理、Host 采集子进程异常、msproftx 打点上报失败等,统一经MSPROF_INNER_ERROR(msprof_error_manager.h)上报为 EK9999。
  • 怎么办:以日志为准。对照本文列出的真实上报点位,找到 EK9999 伴随的具体失败文本,按上表方向处置;无法定位时保留完整日志联系华为工程师。

【免费下载链接】runtime本项目提供CANN运行时组件和维测功能组件。项目地址: https://gitcode.com/cann/runtime

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/19 21:08:31

Windows 11重装后未激活?数字许可证找回全攻略(4种方法)

重装完 Windows 11 满心欢喜地进系统,结果右下角一行"Windows 未激活",设置里看一眼,数字许可证也没了——这场景我见过太多次了,自己也踩过一次。那时候我在重装前忘了确认微软账户有没有绑定数字许可证,装…

作者头像 李华
网站建设 2026/9/19 21:07:29

BrewUI:为Homebrew打造原生图形化界面,让包管理更直观

1. BrewUI 是什么:给 Homebrew 套上一层“看得见”的壳如果你跟我一样,在 macOS 上折腾过一段时间开发环境,那你多半对brew install这行命令再熟悉不过。Homebrew 几乎是 Mac 开发者绕不开的包管理器,装 Node、装 Python、装各种命…

作者头像 李华
网站建设 2026/9/19 21:06:32

Textual 0.18.0 并发管理 Worker API:统一管理 asyncio 任务与线程

Textual 0.18.0 并发管理 Worker API:统一管理 asyncio 任务与线程 【免费下载链接】textual The lean application framework for Python. Build sophisticated user interfaces with a simple Python API. Run your apps in the terminal and a web browser. 项…

作者头像 李华
网站建设 2026/9/19 21:05:34

大语言模型长文本推理优化技术与实践

1. 长上下文推理的挑战与机遇大语言模型在处理长文本时总会遇到一个尴尬局面——当输入内容超过某个临界长度,推理速度就会断崖式下跌。我在实际项目中最常遇到这种情况:法律合同分析需要处理200页PDF,医疗报告总结要解析数十万字的病历记录&…

作者头像 李华
网站建设 2026/9/19 21:02:46

Grafana Tempo 依赖探秘:oklog/ulid Go 实现原理与 ULID 实战指南

Grafana Tempo 依赖探秘:oklog/ulid Go 实现原理与 ULID 实战指南 【免费下载链接】tempo Grafana Tempo is a high volume, minimal dependency distributed tracing backend. 项目地址: https://gitcode.com/GitHub_Trending/tempo1/tempo ULID&#xff08…

作者头像 李华