CANN Runtime 错误码 EH0003 深入解析文件路径非法Invalid Path的触发原理与排查方法【免费下载链接】runtime本项目提供CANN运行时组件和维测功能组件。项目地址: https://gitcode.com/cann/runtime导读EH0003 是 CANN runtimeCANN 运行时组件中一类面向用户的**文件路径非法File Operation Error / Invalid Path**错误码当应用传入的配置文件路径不存在、无法解析或打开失败时runtime 会以Path %s is invalid. Reason: %s.的固定模板向用户报告。本文以 EH0003-File_Operation_Error_Invalid_Path.md 为骨架结合本仓库中该错误码的注册定义、底层格式化实现、两处真实触发源码与对应单元测试完整还原 EH0003 的产生链路并给出从报错信息到根因定位的实战排查步骤。一、错误信息格式EH0003 的报错格式固定如下其中占位符%s的含义依次为文件路径、报错原因Path %s is invalid. Reason: %s.占位符含义典型取值第 1 个%spath传入或解析得到的文件路径/tmp/invalid.json、./a.text第 2 个%sreason具体的失败原因file open failed、无法解析真实路径时的系统错误信息报错示例Path /tmp/invalid.json is invalid. Reason: file open failed.这段报错表达了两层信息第一runtime 认为/tmp/invalid.json这个路径不合法第二非法的原因在于文件打开失败。排查时应优先关注 Reason 部分携带的具体失败原因它直接指向根因方向。二、EH0003 在错误码体系中的位置EH0003 属于ACL ErrorsEH 系列外部错误码。在错误码索引文档 ACL-Errors.md 中EH 系列覆盖了参数非法EH0001/EH0002、文件操作错误EH0003/EH0004、功能不支持EH0006等一系列通用用户侧错误EH0003 的命名即表明其语义为File Operation Error - Invalid Path。从代码注册层面看EH0003 在 runtime 中被统一定义为常量供各模块复用src/acl/common/log_inner.h 中声明了constexpr const char_t* const INVALID_PATH_MSG EH0003;与INVALID_PARAM_MSGEH0001、INVALID_NULL_POINTER_MSGEH0002等并列属于 ACL 公共错误消息常量src/runtime_compact/c_base/src/error_manager.c 的错误码注册表ERROR_MAP中登记了该错误码的完整模板{EH0003, Path %s is invalid. Reason: %s., NULL, NULL, {path, reason}},其中第 5 个字段{path, reason}是参数列表argList它规定了该错误模板各%s位对应的参数名与报错格式中的占位符一一对应。这也是报错格式中第 1 个%s为文件路径、第 2 个%s为报错原因这一约定的代码级来源。ERROR_MAP中的possibleCause与solution字段对 EH0003 均为空说明该错误码不附带固定的原因与解决建议需要根据每次上报时携带的 path 与 reason 动态判断。三、哪些场景会触发 EH0003从源码看触发链路EH0003 并非只在文件不存在这一种场景下出现。在本仓库中至少存在两处明确上报该错误码的源码路径分别位于 runtime 配置读取与 JSON 配置解析两个环节。3.1 场景一runtime 配置路径无法解析或打开失败src/acl/aclrt_impl/acl_rt_impl_base.cpp 中的GetStrFromConfigPath负责把外部传入的配置文件路径读取为字符串它包含两道检查任一失败都会上报 EH0003真实路径解析失败调用mmRealPath(configPath, realPath, MMPA_MAX_PATH)对传入路径做规范化解析若返回非EN_OK例如路径指向不存在的目录、包含无法解析的符号链接、路径过长等则上报acl::AclErrorLogManager::ReportInputError( acl::INVALID_PATH_MSG, std::vectorconst char*({path, reason}), std::vectorconst char*({configPath, formatErrMsg.c_str()})); ACL_LOG_ERROR(Invalid file: %s, configPath); return ACL_ERROR_INVALID_FILE;此时 Reason 携带的是mmGetErrorCode()格式化后的系统错误信息报错示例中的/tmp/invalid.json即属于此类路径形态。文件打开失败路径解析成功后用std::ifstream file(realPath, std::ios::binary)以二进制方式打开文件若打开失败文件不存在、权限不足、被占用等则上报acl::AclErrorLogManager::ReportInputError( acl::INVALID_PATH_MSG, std::vectorconst char*({path, reason}), std::vectorconst char*({configPath, file open failed}));这正是错误码文档中报错示例Reason: file open failed.的源码出处。无论哪一道检查失败函数都会返回ACL_ERROR_INVALID_FILE给上层调用者同时通过日志打印Invalid file: path或Failed to open file: path便于定位。3.2 场景二JSON 配置文件非法路径检查src/acl/common/json_parser.cpp 中JsonParser::IsValidFileName负责在解析 JSON 配置前校验文件名合法性同样有两处 EH0003 上报mmRealPath(fileName, trustedPath, MMPA_MAX_PATH)返回非EN_OK时上报 EH0003Reason 为AclGetErrorFormatMessage(mmGetErrorCode())得到的格式化错误信息同时打印日志[Trans][RealPath]the file path %s is not like a real path, mmRealPath returns %d, errMessage is %smmStatGet(trustedPath, pathStat)获取文件状态失败时再次上报 EH0003Reason 为格式化错误信息对应日志[Get][FileStatus]cannot get config file status, which path is %s, maybe does not exist, return %d, errcode %d。从这段实现可以推断EH0003 的 Reason 部分并不总是固定的 file open failed它可能是一段来自底层系统调用的可读错误描述。因此排查 EH0003 时必须完整读取 Reason 中携带的具体文本而不能只依赖固定的示例。3.3 参数上报机制小结两处触发点都调用了acl::AclErrorLogManager::ReportInputError(INVALID_PATH_MSG, {path, reason}, {path, reason})其参数顺序与ERROR_MAP注册表src/runtime_compact/c_base/src/error_manager.c中的{path, reason}严格对应最终由 error manager 依据模板完成格式化并生成用户可见的报错文本。四、单元测试中的 EH0003 验证runtime 的错误码管理单元测试 tests/ut/runtime/runtime_c/testcase/c_base/error_manager_test.cc 对 EH0003 的格式化行为做了直接验证REPORT_INPUT_ERROR(EH0003, ARRAY(path, reason, value), ARRAY(./a.text, cannot find, 100)); char* errmsg GetErrorMessage(); ASSERT_STREQ( errmsg, EH0001: Value 25 for x is invalid. Reason: The value is too small.\r\n TraceBack (most recent call last):\r\n Argument ll must not be NULL.\r\n Path ./a.text is invalid. Reason: cannot find.\r\n);该用例同时说明了两个重要行为模板格式化正确性传入 path./a.text、reasoncannot find时最终输出Path ./a.text is invalid. Reason: cannot find.与本文开头给出的报错格式完全一致参数冗余容忍即使调用方多传了一个模板参数列表中不存在的value参数ARRAY(path, reason, value)EH0003 仍能正常格式化多余参数不会导致模板错位或格式化失败印证了 error manager 对参数数量的容错处理。五、解决方法与排查步骤5.1 官方解决方法根据错误码文档 EH0003-File_Operation_Error_Invalid_Path.mdEH0003 的解决方法是根据报错检查文件是否存在。5.2 结合源码的完整排查清单仅检查文件是否存在还不够结合 3.1 与 3.2 两处触发源码建议按下述顺序逐项核查读取完整报错先获取完整的 EH0003 文本重点是Reason:之后的具体原因——它可能是file open failed也可能是底层系统调用返回的可读错误描述后者直接决定排查方向。核对文件是否存在使用ls -l、stat等命令确认报错路径对应的文件真实存在且不是指向失效位置的符号链接mmRealPath解析失败同样会触发 EH0003。核对文件类型与权限路径指向的必须是普通文件目录、设备文件等非普通文件在IsValidFileName中会命中非普通文件检查并报错源码见 src/acl/common/json_parser.cpp该分支使用 EH0004 模板当前进程对文件须具备读取权限且父目录具备可访问可执行权限否则std::ifstream打开会失败并报file open failed。核对路径写法尽量使用绝对路径避免依赖进程当前工作目录的相对路径检查路径中是否包含未展开的环境变量、特殊字符或超出MMPA_MAX_PATH的长路径这些都会导致mmRealPath解析失败。结合日志定位EH0003 上报时通常伴随ACL_LOG_ERROR日志输出如Invalid file: path、Failed to open file: pathsrc/acl/aclrt_impl/acl_rt_impl_base.cpp或[Trans][RealPath]...、[Get][FileStatus]...src/acl/common/json_parser.cpp。检索运行日志中与报错路径一致的关键字可确认触发环节是配置读取还是JSON 解析。确认返回码语义在配置读取场景中EH0003 对应的上层返回码是ACL_ERROR_INVALID_FILE见 src/acl/aclrt_impl/acl_rt_impl_base.cpp可在应用侧据此区分错误类别与参数非法EH0001内存不足EH0010等错误码区分处理。六、小结EH0003 是 CANN runtime 面向用户的通用文件路径错误码其报错模板Path %s is invalid. Reason: %s.由错误码注册表 src/runtime_compact/c_base/src/error_manager.c 统一定义实际触发点覆盖 runtime 配置路径读取src/acl/aclrt_impl/acl_rt_impl_base.cpp与 JSON 配置文件名校验src/acl/common/json_parser.cpp两条链路。排查时以报错中的 Reason 为第一线索依次核对文件存在性、文件类型与权限、路径写法并结合运行日志确认触发环节即可快速收敛到根因。【免费下载链接】runtime本项目提供CANN运行时组件和维测功能组件。项目地址: https://gitcode.com/cann/runtime创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考