CANN Runtime 错误码 EE1022(Invalid_Argument)详解:消息格式、触发场景与排查方法
【免费下载链接】runtime本项目提供CANN运行时组件和维测功能组件。项目地址: https://gitcode.com/cann/runtime
导读
EE1022 是 CANN Runtime(RTS Errors 类别)中用于上报"多个参数取值组合非法"的一类错误码。与描述单个参数非法(如 EE1011、EE1017)的错误码不同,EE1022 专门用于描述两个或以上参数的取值本身或许各自合法、但组合在一起违反约束的场景,例如两个输出参数同时为nullptr、或者 Event 与 Stream 分属不同 Device。本文基于 CANN Runtime 开源仓库 中的错误码参考文档、错误码元数据表与 API 实现源码,逐字段解析 EE1022 的消息格式,说明其源码级触发路径、与相近错误码的区别,并给出可落地的排查步骤,帮助开发者在 AIPP/Graph 捕获、内存管理、事件同步等调用链上快速定位非法参数组合。
一、EE1022 在 CANN Runtime 错误码体系中的定位
CANN Runtime 的错误码参考文档按模块划分为 ACL、Dump、FE、Profiling、RTS、TEfusion 等类别,EE 前缀属于 RTS(Runtime System)错误。EE1022 的完整分类信息记录在错误码注册数据 error_code.json 中:
- errClass:
RTS Errors - errTitle:
Invalid_Argument - ErrCode:
EE1022 - Arglist:
func, values, params, reason
在运行时 API 层,EE1022 的枚举成员同样注册在 rt_log.h 的ErrorCode枚举中,并与内部返回码RT_ERROR_INVALID_VALUE绑定使用。也就是说,EE1022 不是普通日志文案,而是 Runtime 对外可检索、可引用的结构化错误码。
在编号语义上,EE10xx 段集中承载参数校验类错误:EE1001 为通用 Invalid Argument,EE1003 用于"单参数取值非法且给出期望值",EE1004 用于"参数不能为空指针",EE1011/EE1012 用于"单参数取值非法",EE1017 用于"单参数非法但无期望值",而EE1022 专门用于"多个参数的取值组合非法",是这一家族中唯一面向组合校验的错误码。
二、错误消息格式与占位符逐字段解析
按照 EE1022-Invalid_Argument.md 的定义,EE1022 的标准消息格式为:
%s failed. Values %s for parameters %s are invalid. Reason: %s.其中 4 个%s占位符按顺序含义如下:
| 占位符 | 含义 | 示例值 |
|---|---|---|
第 1 个%s | 错误发生阶段或 API 名称(func) | MemGetAddressRange |
第 2 个%s | 非法参数的取值列表(values) | nullptr and nullptr |
第 3 个%s | 非法参数的名称列表(params) | pbase and psize |
第 4 个%s | 参数组合非法的具体原因(reason) | Parameters pbase and psize cannot both be nullptr |
文档给出的完整错误示例:
MemGetAddressRange failed. Values nullptr and nullptr for parameters pbase and psize are invalid. Reason: Parameters pbase and psize cannot both be nullptr.需要注意的是,占位符 2 与 3 的值通常用连接词and串联多个取值/参数名,这恰恰体现了 EE1022 "组合校验" 的语义:单独看pbase == nullptr或psize == nullptr都可能合法(例如只查询起始地址或只查询大小),但当两者同时为nullptr时,函数无法返回任何信息,此时才触发 EE1022。
三、完整消息模板与源码级定义
文档中给出的格式是面向用户阅读的精简版。Runtime 内部实际输出的完整模板定义在错误码元数据表 error_code_meta.h 中,使用 X-Macro 表驱动方式注册:
/* EE1022 - Invalid_Argument */ X(EE1022, "EE1022", ("func", "values", "params", "reason"), "%s failed. Values %s for parameters %s are invalid. " "Reason: %s. ErrorCode=EE1022.\n", DLOG_ERROR)这段元数据透露出三个关键信息:
- 参数名列表为
func, values, params, reason,与文档中的占位符顺序一一对应,参数名会被错误码框架用于格式化与自解释; - 完整模板以
ErrorCode=EE1022.结尾并带有换行符,这是对外日志中可检索的稳定后缀,也是用户能在 plog 中通过EE1022关键字过滤日志的依据; - 日志级别为
DLOG_ERROR,说明 EE1022 属于 Error 级别错误,通常伴随 API 返回非零错误码。
该元数据表由错误码框架统一消费,例如 error_message_manage.hpp 中定义的COND_RETURN_AND_MSG_OUTER系列宏(如COND_RETURN_AND_MSG_OUTER_WITH_PARAM_NAME_AND_FUNC_DESC、COND_RETURN_AND_MSG_OUTER_WITH_PARAM_AND_FUNC_DESC),以及RT_LOG_OUTER_MSG_IMPL、PrintErrMsgToLog等输出接口,负责将校验条件、RT 返回码、ErrorCode 与参数值拼装成上述完整日志。这意味着开发者只需要调用方侧提供func / values / params / reason四个参数,框架即可保证消息格式全局统一。
四、EE1022 的典型触发场景(源码证据)
结合仓库源码,EE1022 目前至少出现在以下三条调用链上,可作为理解该错误码语义的实例。
4.1 内存地址区间查询:MemGetAddressRange
这是错误码参考文档自带的示例来源,实现在 api_error.cc:
rtError_t ApiErrorDecorator::MemGetAddressRange(void* ptr, void** pbase, size_t* psize) { NULL_PTR_RETURN_MSG_OUTER_WITH_FUNC_DESC( ptr, RT_ERROR_INVALID_VALUE, "Obtaining the start address and size of the memory block to which the address to be queried belongs"); COND_RETURN_AND_MSG_OUTER( (pbase == nullptr) && (psize == nullptr), RT_ERROR_INVALID_VALUE, ErrorCode::EE1022, "Obtaining the start address and size of the memory block to which the address to be queried belongs", "nullptr and nullptr", "pbase and psize", "Parameters pbase and psize cannot both be nullptr"); return impl_->MemGetAddressRange(ptr, pbase, psize); }该校验逻辑清晰展示了 EE1022 的组合语义:
- 入参
ptr(待查询地址)为空的场景由空指针宏单独拦截,返回RT_ERROR_INVALID_VALUE但不使用EE1022; - 只有当两个输出参数
pbase与psize同时为nullptr时(条件(pbase == nullptr) && (psize == nullptr)),才命中 EE1022。这是因为该接口允许调用方只取其中一个输出(如只关心内存块起始地址),只有"两个都不想要"才是非法组合。
4.2 Event 与 Stream 分属不同 Device
在 api_impl.cc 的CheckEventAndStreamDevice校验函数中,当 Event 与 Stream 不在同一 Device 上操作时会触发 EE1022:
COND_RETURN_AND_MSG_OUTER( evtDevice->Id_() != stmDevice->Id_(), RT_ERROR_INVALID_VALUE, ErrorCode::EE1022, funcDesc, RtFmtMsg("%u and %u", evtDevice->Id_(), stmDevice->Id_()), "event device ID and stream device ID", RtFmtMsg( "The event and stream (stream_id=%d) belong to different devices. Create them on the same device", stm->Id_()));这里的values被格式化为"evtDeviceId and stmDeviceId",params为"event device ID and stream device ID",reason明确指出"Event 与 Stream 必须创建在同一个 Device 上"。这说明 EE1022 不仅覆盖空指针组合,也覆盖跨 Device 的上下文组合非法,在多 Device 编程场景中尤为常见。
4.3 ACL Graph 捕获状态查询
在 ACL Graph 特性模块 api_error_aclgraph.cc 中,同样使用了 EE1022:
(status == nullptr) && (captureMdl == nullptr), RT_ERROR_INVALID_VALUE, ErrorCode::EE1022,即调用方在查询图捕获状态时,两个输出参数status与captureMdl同时为空才构成非法组合。这与 4.1 的结构完全一致,进一步印证了 EE1022 "多输出/多上下文参数组合校验" 的通用定位。
五、与相近错误码的区分(避免误判)
排查时容易将 EE1022 与同家族的 Invalid_Argument 错误码混淆,它们的差异在于校验对象的粒度:
| 错误码 | 消息模板要点 | 适用场景 |
|---|---|---|
| EE1022 | Values %s for parameters %s are invalid | 多个参数取值组合非法(含多输出同时为空、跨 Device 组合等) |
| EE1003 | value %s for parameter %s is invalid. Expected value: %s | 单个参数取值非法,且能给出期望值区间 |
| EE1011 | Value %s for parameter %s is invalid. Reason: %s | 单个参数取值非法,附带原因 |
| EE1012 | Value %s for %s is invalid. Reason: %s | 单个对象/参数取值非法 |
| EE1017 | Parameter %s is invalid. Reason: %s | 单个参数非法(不展示取值) |
| EE1004 | %s cannot be a NULL pointer | 单个参数不能为空指针 |
模板细节见 error_code_meta.h。区分要点是:如果错误消息中出现了and连接的多个值/参数名,基本可以判定为 EE1022;如果只涉及单个参数,则应结合期望值/原因字段定位到 EE1003、EE1011 或 EE1017。
六、排查与解决步骤
原文档给出的解决方案分两步:检查函数入参取值范围、检查函数调用关系。结合源码可以展开为如下可操作流程:
对照 API 头文件确认参数语义:打开触发错误时使用的 API 声明(如
rtMemGetAddressRange对应 include/external/acl/acl_rt.h,以及 rt_external_mem.h 等对外头文件),逐一核对每个参数的合法取值与"输出参数是否允许为空"的约定。EE1022 的params字段会明确列出是哪几个参数构成非法组合。检查函数调用关系:EE1022 的
func字段给出的是失败阶段或 API 名,如果错误发生在装饰器层(ApiErrorDecorator),说明是入参尚未进入业务实现就被校验拦截;此时应重点检查本次调用的参数来源——例如 4.2 中的 Event/Stream 是否在同一个aclrtSetDevice之后创建,4.1 中的输出指针是否在栈上正确初始化。仓库中CheckEventAndStreamDevice这类校验函数就是典型的内层调用关系检查点。结合
reason字段判断根因:reason是定位的核心,例如 "Parameters pbase and psize cannot both be nullptr" 直接指明修复方式(至少传入一个非空输出参数);"The event and stream belong to different devices" 则提示需要调整 Device 上下文归属。区分组合非法与单参数非法:如果日志中只有一个参数名,应改用 EE1011/EE1017/EE1003 对应的排查路径,不要套用多参数组合的思路。
七、日志检索与验证
- 检索关键字:完整日志以
ErrorCode=EE1022.结尾,因此在 runtime 日志(plog)中直接搜索EE1022即可定位全部相关输出;如需确认格式化是否一致,可对照 error_code.json 中注册的ErrMessage模板。 - 单测验证:Runtime 错误码单测 rt_error_code_test.cc 与 rt_error_code_test.cc 分别通过
PrintErrMsgToLog与RT_LOG_OUTER_MSG_IMPL验证了 EE1022 的消息拼装,示例中使用的正是rtUbDbSend、nullptr and nullptr、pbase and psize这一组参数,可用于对照预期输出格式。 - 日志级别:EE1022 以
DLOG_ERROR级别输出,默认日志配置即可捕获;若日志未刷新,可参考 如何获取和解读Runtime异步错误码 与 日志级别设置 调整日志输出。
八、相关资源
- 英文错误码参考:EE1022-Invalid_Argument.md、RTS 错误码总览 RTS-Errors.md
- 中文错误码参考:EE1022-Invalid_Argument.md
- 错误码元数据表:error_code_meta.h
- 错误码注册数据:error_code.json
- 错误码输出宏定义:error_message_manage.hpp
- 触发点源码:api_error.cc、api_impl.cc、api_error_aclgraph.cc
- 错误码消息编写与宏选用指南:error-code-guide.md、message-examples.md、macro-selection-guide.md
【免费下载链接】runtime本项目提供CANN运行时组件和维测功能组件。项目地址: https://gitcode.com/cann/runtime
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考