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

资讯详情

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

CANN Runtime 错误码 EE1014 深度解析:算子二进制文件解析失败(File_Operation_Error_Parse)

CANN Runtime 错误码 EE1014 深度解析:算子二进制文件解析失败(File_Operation_Error_Parse) CANN Runtime 错误码 EE1014 深度解析算子二进制文件解析失败File_Operation_Error_Parse【免费下载链接】runtime本项目提供CANN运行时组件和维测功能组件。项目地址: https://gitcode.com/cann/runtimeEE1014 是 CANN Runtime本仓库cann/runtime在加载与解析算子二进制ELF文件时上报的典型错误归属于 RTS-Errors 错误码体系中的文件操作类错误。本文以 EE1014 官方错误码文档为主体结合仓库中错误码定义、ELF 解析源码与单元测试逐层拆解该错误的报错格式、底层触发链路、常见成因与排查方案帮助开发者快速定位并解决算子二进制解析失败的问题。错误码速览属性内容错误码EE1014错误类别RTS ErrorsRuntime 系统错误错误标题File_Operation_Error_Parse文件操作类错误——解析失败典型触发阶段算子二进制ELF文件加载与解析日志级别DLOG_ERROR该错误码在错误码定义文件中登记为{ errClass: RTS Errors, errTitle: File_Operation_Error_Parse, ErrCode: EE1014, ErrMessage: Failed to parse the binary file of the operator. Reason: %s., Arglist: reason, suggestion: { Possible Cause: 1. The binary file of the operator is damaged. 2. The build parameter is incorrect., Solution: Rebuild and load the binary file of the operator. } }定义位置src/dfx/error_manager/error_code.json。同一条目也以宏形式注册在 src/runtime/core/inc/common/error_code_meta.h 中用于 Runtime 侧实际输出日志。报错格式与实例标准报错格式错误信息由固定前缀与占位符组成%s为具体的解析失败原因Failed to parse the binary file of the operator. Reason: %s.实际输出时日志会附加ErrorCodeEE1014后缀。这一点可以从 Runtime 的错误码注册宏中得到印证其打印格式为Failed to parse the binary file of the operator. Reason: %s. ErrorCodeEE1014.即真实日志形如Failed to parse the binary file of the operator. Reason: The ELF section header address in the operator binary ELF file header cannot be empty. ErrorCodeEE1014.官方文档中的报错示例以The ELF section header address in the operator binary ELF file header cannot be empty为具体原因的示例Failed to parse the binary file of the operator. Reason: The ELF section header address in the operator binary ELF file header cannot be empty.该示例并非虚构它对应的正是 Runtime ELF 解析实现中Get64bitSectionHeaders()对 ELF 节区头section header地址为空的校验分支见下文“底层触发链路”。参考EE1014-File_Operation_Error_Parse.md英文 与 中文对照文档。错误码在 Runtime 中的登记与输出方式在 Runtime 侧EE1014 通过错误码注册宏X(...)声明携带一个参数reason并指定日志级别为DLOG_ERROR/* EE1014 - File_Operation_Error_Parse */ X(EE1014, EE1014, (reason), Failed to parse the binary file of the operator. Reason: %s. ErrorCodeEE1014.\n, DLOG_ERROR)代码位置src/runtime/core/inc/common/error_code_meta.h。RT_LOG_OUTER_MSG_IMPL是该仓库中面向用户的错误输出宏ELF 解析模块正是通过它来携带具体reason上报 EE1014。从错误码区间看EE1013主机内存不足属于资源类错误EE1015驱动版本能力不足属于包版本类错误而 EE1014 独立成类为文件操作类解析错误说明 Runtime 对“算子二进制解析失败”这一场景单独做了错误归类便于用户根据错误码快速定位问题所属模块。底层触发链路算子二进制是如何被解析的理解 EE1014 的触发点需要先了解算子二进制在 Runtime 中的加载流程。该错误在 ELF 解析阶段抛出核心代码位于 src/runtime/core/src/kernel/elf.cc调用链如下ElfProgram::ParserBinary() // program.cc程序二进制解析入口 └─ ProcessObject() // elf.cc整体解析流程编排 ├─ GetFileHeader() // 校验并读取 ELF 文件头仅支持 64 位 ELF └─ ProcessSymbolTable() // 解析节区头、字符串表、符号表并产出 RtKernel ├─ Get64bitSectionHeaders()// 读取并校验 ELF 节区头 ├─ GetStringTable() // 获取字符串表 ├─ ParseKernelMetaData() // 解析算子元数据TLV 格式 ├─ ParseElfStackInfoHeader()/ParseElfStackInfoFromSection() ├─ ProcessDynamicSection() // 处理动态段 └─ GetKernels() // 汇总生成内核句柄列表1. 解析入口ElfProgram::ParserBinary算子二进制以ElfProgram的形式管理。ParserBinary()首先将二进制内容与大小灌入rtElfData随后调用ProcessObject()完成解析解析失败即返回错误rtError_t ElfProgram::ParserBinary() { NULL_PTR_RETURN_MSG(elfData_, RT_ERROR_PROGRAM_DATA); ... elfData_-obj_size binarySize_; kernels_ ProcessObject(RtPtrToPtrchar_t*(binary_), elfData_); NULL_PTR_RETURN_MSG_OUTER_WITH_FUNC_DESC( kernels_, RT_ERROR_INVALID_VALUE, Parsing the binary file data of the operator); ... }代码位置src/runtime/core/src/kernel/program.cc。可以看到“Parsing the binary file data of the operator”正是该入口对解析动作的描述与 EE1014 错误信息中的 “binary file of the operator” 一一对应。2. 文件头校验GetFileHeaderGetFileHeader()负责读取 ELF 头部的标识区e_ident并决定字节序解析函数同时校验 ELF 位数——Runtime 只支持 64 位 ELF若检测到 32 位对象会直接上报 EE1014const bool is32bitElf (static_castint32_t(elfData-elf_header.e_ident[EI_CLASS]) ! ELFCLASS64); if (is32bitElf) { RT_LOG_OUTER_MSG_IMPL(ErrorCode::EE1014, The ELF file must be a 64-bit file); return ELF_FAIL; }代码位置src/runtime/core/src/kernel/elf.cc。这意味着“编译参数不正确”导致的 32 位产物、或文件头损坏导致EI_CLASS字段异常都会在此处命中 EE1014。3. 节区头解析Get64bitSectionHeaders 的多重校验Get64bitSectionHeaders()是 EE1014 报错最密集的函数围绕 ELF 节区头做了多维度合法性校验任何一项不满足都会上报 EE1014e_shentsize / e_shnum 合理性校验节区头大小与节区数量均不能为 0且二者的乘积不能超过uint64_t最大值否则上报The value %u of e_shentsize or the value %u of e_shnum in the operator binary ELF file header is incorrect...代码位置src/runtime/core/src/kernel/elf.cc。e_shentsize 一致性校验必须与Elf64_External_Shdr的实际大小一致否则上报The value %u of e_shentsize in the operator binary ELF file header must be equal to the size %u of the ELF section header代码位置src/runtime/core/src/kernel/elf.cc。节区头地址非空校验根据e_shoff计算出的节区头指针为空时正是官方文档示例中的报错The ELF section header address in the operator binary ELF file header cannot be empty代码位置src/runtime/core/src/kernel/elf.cc。节区偏移越界校验第 i 个节区的偏移超过 ELF 对象总大小时上报The offset %llu of the section ranked %u exceeds the size %llu of the ELF object代码位置src/runtime/core/src/kernel/elf.cc。sh_link 越界校验节区关联索引超出节区总数范围[0, num]时上报代码位置src/runtime/core/src/kernel/elf.cc。4. 符号表与元数据解析在符号表解析Get64bitElfSymbols()中还会校验节区大小sh_size大于 0、sh_entsize位于(0, sh_size]区间以及符号表偏移是否越界失败均上报 EE1014src/runtime/core/src/kernel/elf.cc。此外ProcessSymbolTable()在汇总代码段text section大小时若发生整数溢出风险同样上报 EE1014src/runtime/core/src/kernel/elf.cc。从以上校验点可以总结出 EE1014 的本质它是一组“ELF 结构合法性”校验失败的统一出口任何导致 ELF 头、节区头、符号表结构异常的输入都会收敛到这个错误码。可能原因分析根据官方文档英文版 / 中文版的说明EE1014 的可能原因有两点算子的二进制文件损坏文件在传输、落盘或裁剪过程中被破坏导致 ELF 头字段缺失或数值非法例如e_shoff指向无效地址、e_shentsize异常、节区偏移越界从而命中上述各种校验分支。编译参数不正确编译产物不符合 Runtime 的解析约束。最典型的例子是产出了 32 位 ELF不满足“仅支持 64 位 ELF”的硬性要求此外SoC 版本、工具链选项、编译宏等与目标环境不匹配也可能生成结构上不合法或无法被当前 Runtime 识别的二进制。结合源码还可以补充推断凡是在GetFileHeader()、Get64bitSectionHeaders()、Get64bitElfSymbols()等校验点失败的情况都会以“Reason: xxx”的形式填充到 EE1014 的%s占位符中因此报错原因部分本身就有极强的定位价值——它直接指出了是文件头、节区头还是符号表哪个环节不合法。排查与解决方法官方文档给出的解决方法是Rebuild and load the binary file of the operator.重新编译并加载算子的二进制文件。在此基础上结合本文的源码分析可以给出更完整的排查路径第一步读取完整报错信息EE1014 的Reason字段是首要线索请从 plog 日志中抓取完整错误行含ErrorCodeEE1014后缀并根据 Reason 文本判断命中哪个校验分支含e_shentsize/e_shnum→ 文件头被破坏或头字段异常含cannot be empty→ 节区头地址e_shoff无效文件头被截断或篡改含exceeds the size→ 节区/符号偏移越界文件内容与头部信息不一致含must be a 64-bit file→ 编译参数错误产物为 32 位。第二步核对编译参数并重新编译确认使用的编译工具链与目标 SoC 型号匹配生成 64 位 ELF 产物检查编译选项、链接脚本和裁剪步骤避免 strip 掉必要的节区如.strtab、.symtab及算子元数据所在节区清理构建缓存后重新生成算子二进制并比对新旧文件的哈希值排除缓存污染。第三步重新加载与验证将重新编译生成的二进制通过正常的加载流程参考仓库 example/2_advanced_features/kernel 中的内核加载示例重新下发到 Runtime并再次观察日志。若错误消失则确认问题出在旧二进制文件本身。第四步回归测试验证仓库的单元测试覆盖了 ELF 解析的正反向用例详见下一节可在本地复现与验证解析逻辑用于确认新产物能通过全部合法性校验。单元测试佐证仓库为 ELF 解析链路提供了系统的单元测试主要位于 tests/ut/runtime/runtime/test/rt_utest_elf.cc不同平台目录如tests/ut/runtime/runtime/test/platform/910B/rt_utest_elf.cc、tests/ut/runtime/runtime/test/platform/950/rt_utest_david_elf.cc下还有平台相关的补充用例。测试以ELFTest为 fixture通过构造二进制缓冲区直接调用ProcessObject()验证解析结果覆盖了正常二进制的符号表、内核信息解析非法输入空指针、损坏的 ELF 结构下解析失败并正确释放资源算子元数据 TLV 解析参数汇总、参数信息等例如ElfParseParamSummary_Success、ElfParseParamInfo_Success等用例。此外tests/ut/runtime/runtime/test/rt_error_code_test.cc 覆盖了错误码本身的注册与输出格式校验。这些测试既验证了 EE1014 所关联的解析逻辑的正确性也为开发者修改 ELF 解析代码提供了回归保障。相关参考EE1014 官方错误码文档英文EE1014 官方错误码文档中文RTS 错误码索引英文RTS 错误码索引中文错误码定义文件错误码注册宏ELF 解析实现ELF 程序解析入口ElfProgram::ParserBinaryELF 解析单元测试错误信息编写指南【免费下载链接】runtime本项目提供CANN运行时组件和维测功能组件。项目地址: https://gitcode.com/cann/runtime创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表