尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

CANN Runtime 错误码 EE1001 排查指南:Invalid Argument 的触发场景、底层原理与定位方法

CANN Runtime 错误码 EE1001 排查指南:Invalid Argument 的触发场景、底层原理与定位方法 CANN Runtime 错误码 EE1001 排查指南Invalid Argument 的触发场景、底层原理与定位方法【免费下载链接】runtime本项目提供CANN运行时组件和维测功能组件。项目地址: https://gitcode.com/cann/runtime导读在基于 CANN Runtime 开发昇腾应用时EE1001Invalid Argument是最常见的一类错误码它表示调用 Runtime 接口时传入了非法参数。本文以 EE1001-Invalid_Argument.md 为核心结合本仓库src/runtime下的错误码元数据定义、日志上报宏与单测用例完整解析 EE1001 的报错格式、典型触发场景、源码级生成原理以及系统化的排查步骤。读完本文你将能够根据日志中%s给出的具体原因快速定位是哪个函数、哪个参数、哪个取值越界并掌握检查参数范围与调用关系两大核心排障手段。一、错误码概览EE1001 是什么EE1001是 CANN RuntimeRTS对外暴露的错误码之一语义为Invalid Argument参数非法。在 RTS-Errors.md 的错误码列表中它排在首位归属于 Runtime 输入类错误。从错误码枚举定义看EE1001是 Runtime 错误码体系中的一个正式成员定义于 rt_log.h 的ErrorCode枚举中enum class ErrorCode { EE_NO_ERROR 0, EE1001, EE1002, EE1003, ... };同时在 base_info.hpp 中它被以字符串常量形式映射为static constexpr const char_t* RT_INVALID_ARGUMENT_ERROR EE1001;也就是说Runtime 内部凡是参数非法类型的失败最终都会以EE1001作为对外可见的错误码字符串进行上报。需要说明的是EE1001是通用型参数非法错误码其具体失败原因完全由消息中的%s占位符内容决定针对空指针参数取值非法但附带期望值参数非法且带原因等更细分的场景Runtime 还提供了 EE1004、EE1003、EE1011/EE1012、EE1017 等专项错误码详见本文第六节。二、错误表现日志中的 EE1001 长什么样2.1 标准错误格式根据 EE1001-Invalid_Argument.md 的说明EE1001 的报错格式如下其中占位符%s表示具体的错误原因The argument is invalid. Reason: %s在仓库的 error_code_meta.h 中可以找到 EE1001 的完整消息模板定义它采用 X-MacroRUNTIME_ERROR_CODE_TABLE方式统一管理这是日志中实际打印内容的权威出处/* EE1001 - Invalid_Argument */ X(EE1001, EE1001, (extend_info), The argument is invalid. Reason: %s. ErrorCodeEE1001.\n, DLOG_ERROR)对比可以发现实际打印的消息在Reason: %s之后还会追加ErrorCodeEE1001后缀并以换行结尾同时该错误码的日志级别为DLOG_ERROR。模板中声明的参数名列表只有一个extend_info即错误码上报时只携带一条补充说明信息这条信息就是%s的填充内容。2.2 错误示例原文档给出了一个非常典型的真实报错The argument is invalid.Reason: Invalid device ID 8. Set drv devId to 8. The valid device range is [0, 7).这条报错的含义是应用调用某个接口时传入了device ID 8但当前环境合法的设备号范围是[0, 7)即 0 到 6 共 7 个设备8 越界因此被判定为参数非法。消息中同时给出了当前传入值 8和合法范围 [0, 7)两组信息可直接据此修正调用代码。2.3 典型触发场景从 EE1001 的语义以及 Runtime 各模块的使用情况来看出现该错误码的高频场景包括设备号Device ID越界如上面的示例传入的 device ID 大于等于实际设备总数。参数取值不在合法枚举/范围内例如 Stream 优先级、Event flag、内存拷贝方向copy kind、日志级别等枚举值传入非法数值。参数为 0 但语义上不允许为 0例如要求非零的大小、数量或句柄值。调用了当前软硬件环境不支持的功能从 error_message_manage.cc 的FuncErrorReason实现可以看到RT_ERROR_INVALID_VALUE、RT_ERROR_CONTEXT_NULL、RT_ERROR_FEATURE_NOT_SUPPORT等内部错误码都会走RT_INVALID_ARGUMENT_ERROR即 EE1001路径上报。三、源码级原理EE1001 是如何生成与上报的3.1 统一的错误码元数据表Runtime 将所有对外错误码集中维护在 error_code_meta.h 的RUNTIME_ERROR_CODE_TABLEX-Macro 表中。每行宏展开后包含五个要素要素EE1001 的值说明枚举名EE1001程序内使用的枚举标识字符串名EE1001对外展示/上报的错误码字符串参数名列表(extend_info)消息模板中的占位参数完整消息模板The argument is invalid. Reason: %s. ErrorCodeEE1001.\n最终打印的日志内容日志级别DLOG_ERROR错误级日志这种方式的好处是新增或修改错误码时只需修改表中一行消息模板、参数解析、日志打印、错误上报全部由统一框架生成保证格式一致。3.2 EE1001 专用上报宏在 error_message_manage.hpp 中为 EE1001 定义了专用宏// EE1001 错误码专用 #define COND_RETURN_OUT_ERROR_MSG_CALL(COND, ERRCODE, format, ...) \ if (COND) { \ RT_LOG_OUTER_MSG(RT_INVALID_ARGUMENT_ERROR, format, ##__VA_ARGS__); \ return ERRCODE; \ } #define COND_PROC_RETURN_OUT_ERROR_MSG_CALL(COND, ERRCODE, PROC, format, ...) \ if (COND) { \ PROC; \ RT_LOG_OUTER_MSG(RT_INVALID_ARGUMENT_ERROR, format, ##__VA_ARGS__); \ return ERRCODE; \ }这两个宏的行为是当条件COND成立即参数校验失败时先把格式化的原因信息写入日志错误码固定为RT_INVALID_ARGUMENT_ERROR EE1001然后可选的执行清理动作PROC最后返回对应的运行时错误码ERRCODE。因此EE1001 的日志上报与返回值是成对出现的——上层既能拿到rtError_t返回值也能在日志中看到带原因的 EE1001 消息。3.3 内部错误码到 EE1001 的映射并非所有 EE1001 日志都直接由业务代码写死很大一部分来自 error_message_manage.cc 中FuncErrorReason的统一映射switch (rtErrCode) { case RT_ERROR_INVALID_VALUE: RT_LOG_OUTER_MSG(RT_INVALID_ARGUMENT_ERROR, %s execution failed., funcName); break; case RT_ERROR_CONTEXT_NULL: RT_LOG_OUTER_MSG(RT_INVALID_ARGUMENT_ERROR, %s execution failed, %s., funcName, RT_GET_ERRREASON(rtErrCode).c_str()); break; case RT_ERROR_FEATURE_NOT_SUPPORT: RT_LOG_OUTER_MSG(RT_INVALID_ARGUMENT_ERROR, %s execution failed, %s., funcName, RT_GET_ERRREASON(rtErrCode).c_str()); break; ... }从这段代码可以看出 EE1001 消息中%s内容的几种形态%s execution failed.——仅给出失败函数名%s execution failed, %s.——给出失败函数名 内部错误码对应的原因描述由RT_GET_ERRREASON从内部错误码反查得到业务侧自定义描述——例如本文示例中的Invalid device ID 8. Set drv devId to 8. The valid device range is [0, 7).这意味着排查时只要抓住Reason:之后到ErrorCodeEE1001之间的文本就能拿到最关键的原因信息。四、定位方法两个核心排查步骤原文档给出的解决方案只有两条但非常精炼这里结合 Runtime 的实现展开说明。4.1 步骤一检查所调用函数的输入参数范围EE1001 的本质是参数校验未通过因此第一步永远是回到你调用的那个 API核对每个入参是否满足其约束。建议按以下顺序检查数值范围参数是否位于文档/头文件声明的合法区间。以设备号为例可调用aclrtGetDeviceCount获取设备总数 N合法的 device ID 应为[0, N)而报错中的[0, 7)正对应 N7 的环境。凡是越界类原因Invalid device ID、out of range 等修正取值即可。枚举/标志位参数是否使用了未定义的枚举值或未开启的标志位组合例如 Stream 的优先级、Event 的标志、内存拷贝方向等应严格使用头文件acl_rt_api.h、acl_base_rt.h中定义的合法值。指针与句柄若消息提示的是空指针或非法句柄通常对应 EE1004/EE1017 而非 EE1001但如果出现于 EE1001 消息中也应检查对象是否已正确创建、是否在错误 Context 下使用Context 归属问题多表现为 EE1010。大小与数量要求非零的大小/数量参数是否被传成了 0内存对齐要求是否满足。4.2 步骤二检查函数调用关系一部分 EE1001 并非参数本身非法而是调用上下文不合法导致参数间接失效因此第二步是检查调用关系前置条件是否满足例如在aclrtSetDevice之前未完成aclrtInit、在未创建的 Context/Stream 上执行操作、在错误的 Device 上访问资源等都可能以参数非法形式暴露出来。可对照 02_initialization_and_deinitialization.md、06_stream_management.md 等接口文档核对初始化与资源创建的先后顺序。调用链上的值传递设备号、Stream、Context 等句柄如果经过多跳函数传递中间某层可能发生脏值或类型错配最终在底层校验处触发 EE1001。可结合应用侧日志与 如何通过plog日志定位Device侧异常 给出的方法沿调用栈逐层核对实际传入值。多 Device 场景多 Device 应用中最常见的就是句柄属于 Device A却拿到 Device B 上使用这类跨设备误用若未被归属校验EE1010拦下也会落入参数非法范畴可参考 多Device场景下Stream跨Device下发失败 的排查思路。4.3 结合返回值与日志的双通道定位Runtime 的错误上报是日志 返回值双通道的。应用代码中应始终检查每个 Runtime API 的aclError/rtError_t返回值遇到非 0 时与日志中的ErrorCodeEE1001消息对照。日志中Reason:之后的文本是定位的锚点而返回值用于判断失败发生在哪一层调用。关于异步场景下错误码与日志的配合使用可参考 如何获取和解读Runtime异步错误码。五、测试用例佐证错误码框架如何被验证仓库的单测覆盖了 EE1001 的打印与参数管理逻辑可在 rt_error_code_test.cc 中看到相关验证直接以 EE1001 调用日志打印接口并传入原因字符串验证消息格式正确如第 74 行PrintErrMsgToLog(ErrorCode::EE1001, file, 1000, func, values1001);通过RT_LOG_OUTER_MSG_IMPL(ErrorCode::EE1001, The argument is invalid)验证对外上报宏的输出第 166 行调用GetParamNames(ErrorCode::EE1001)验证参数名列表解析第 206 行并且第 271 行断言了{ErrorCode::EE1001, 1}即EE1001 只声明了一个参数extend_info与元数据表中的定义完全一致。此外在 rt_utest_api_device.cc 中还有一条值得注意的约束Expected not-support behavior must not trigger the fallback ErrMsg(EE1001) reporting.——即不支持类失败不应被错误地降级成 EE1001 上报这说明测试层面也保证了 EE1001 只用于真正的参数非法场景避免误报干扰排查。六、与相邻错误码的区分Runtime 提供了多枚参数类错误码排查时可根据日志中的ErrorCode后缀区分语义避免误用排查方向错误码语义消息特征EE1001通用参数非法The argument is invalid. Reason: %s.EE1003参数值非法并给出期望值... value %s for parameter %s is invalid. Expected value: %s.EE1004空指针... %s cannot be a NULL pointer.EE1011 / EE1012参数值非法并给出原因... Value %s for parameter %s is invalid. Reason: %s.EE1017指定参数非法并给出原因... Parameter %s is invalid. Reason: %s.EE1018API 调用顺序非法... Reason: %s.EE1010对象不属于当前 Context... does not belong to the current context.所有上述模板同样可在 error_code_meta.h 的元数据表中查到权威定义。当日志中出现的是 EE1003/EE1004/EE1017 等专项错误码时说明 Runtime 已经帮你把值、参数名、期望值/原因拆解得更细直接按消息提示修正即可而当出现的是通用 EE1001 时则更需要依赖Reason:文本自行判断。七、总结EE1001 Invalid Argument是 CANN Runtime 中最基础也最常见的错误码之一其定位逻辑可以浓缩为三步读 Reason定位日志中Reason:之后到ErrorCodeEE1001之间的文本它直接给出了非法参数的具体原因查参数回到调用函数逐一核对参数取值是否越界、枚举是否合法、指针句柄是否有效、大小数量是否非零查调用关系核对初始化、设备设置、Context/Stream 创建等前置条件是否满足确认参数在调用链上没有发生错配。结合本仓库的 error_code_meta.h错误码模板权威定义、error_message_manage.hppEE1001 专用上报宏以及 error_message_manage.cc内部错误码映射你不仅能看懂日志还能理解 EE1001 从参数校验失败到日志落地的完整链路在多层调用栈中快速锁定问题根因。【免费下载链接】runtime本项目提供CANN运行时组件和维测功能组件。项目地址: https://gitcode.com/cann/runtime创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表