CANN Runtime 错误码 EP0004 全解析:Dump 配置文件解析失败的定位与修复指南
2026/9/19 14:40:36 网站建设 项目流程

CANN Runtime 错误码 EP0004 全解析:Dump 配置文件解析失败的定位与修复指南

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

导读

EP0004(File Operation Error - Parse)是 CANN Runtime 中 adump 数据采集组件上报的"配置文件解析失败"错误码,用于标识acl.json等 Dump 配置 JSON 文件无法通过语法解析的场景。本文基于开源仓库cann/runtime中的错误码参考文档,结合src/dfx/adump下的真实实现与单元测试,完整拆解该错误码的报文格式、触发链路、典型原因与排查方法。读者阅读后可准确解读 EP0004 报错中的每个占位符含义,并据此快速修复异常的 Dump 配置文件。

错误码概览:EP 系列在 Dump 错误体系中的定位

EP0004 属于 "DUMP Errors"(Dump 错误)错误类,在 Dump 错误码索引 中与其姊妹错误码共同构成一套完整的 Dump 配置校验错误体系:

错误码错误标题语义
EP0001Config Error配置项内容无效
EP0002Config Error配置项取值无效(给出期望值)
EP0003Config Error配置项取值无效(给出原因)
EP0004File Operation Error - Parse配置文件解析失败
EP0005Config Error配置项之间存在冲突
EP0006Invalid Argument参数取值无效
EP0007Invalid Argument - Null Pointer参数为空指针
EP0008Invalid Argument - API Call SequenceAPI 调用顺序错误

从语义上看,EP0004 是其中唯一一个面向"文件整体解析"(而非单个配置项)的错误码:当 Dump 配置 JSON 文件在语法层面无法被解析时触发,而字段类型、取值、冲突等语义层面的问题则分别由 EP0001/EP0002/EP0003/EP0005 负责。这一分工可以在仓库的错误码注册表中得到直接印证,见 error_code.json:

{ "errClass": "DUMP Errors", "errTitle": "File_Operation_Error_Parse", "ErrCode": "EP0004", "ErrMessage": "Failed to parse file %s. Reason: %s.", "Arglist": "path,reason", "suggestion": { "Possible Cause": "N/A", "Solution": "N/A" } }

错误信息格式与字段含义

EP0004 的标准报错格式(见 官方文档):

Failed to parse file %s. Reason: %s.

两个占位符%s的含义依次为:

占位符含义对应 Arglist
第 1 个%s配置文件路径(file name / path)path
第 2 个%s解析失败的具体原因(error cause / reason)reason

官方给出的报错示例如下:

Failed to parse file /home/test_dump/acl.json. Reason: [json.exception.type_error.302] type must be array, but is string.

在这个例子中,/home/test_dump/acl.json是待解析的配置文件路径,而[json.exception.type_error.302] type must be array, but is string则是底层 JSON 解析器抛出的异常描述。从异常前缀json.exception.type_error.302可以推断,解析工作由 nlohmann/json 库执行——这一点与下文源码实现中的调用保持一致。

触发链路:EP0004 从哪里来

EP0004 并非由人工手写抛出,而是由 adump 组件在 Dump 配置转换流程中自动上报。整条链路如下:

1. 上报宏定义

EP0004 的上报入口封装在 adump_error_manager.h 中:

// EP0004 Parse Error Report Macro - Inline for performance #define REPORT_EP0004_PARSE_ERROR(moduleName, reason, configPath) \ do { \ IDE_LOGE("[%s] Parse failed: %s", moduleName, ADUMP_TO_CSTR(reason)); \ ADUMP_INPUT_ERROR( \ "EP0004", std::vector<std::string>({"path", "reason"}), std::vector<std::string>({configPath, reason})); \ } while (0)

该宏做了两件事:

  • 通过IDE_LOGE在本地日志中记录[模块名] Parse failed: 原因
  • 通过ADUMP_INPUT_ERROR将错误码EP0004及参数path(配置文件路径)、reason(解析原因)上报到错误管理模块,最终按error_code.json中的模板格式化输出。

注意宏体中传入的path参数名为configPath,说明该错误码的"文件"实际上特指 Dump 配置文件。

2. JSON 语法解析:JsonParser::ParseJsonFromMemory

EP0004 的根因在于 JSON 语法解析失败,解析动作由 json_parser.cpp 中的ParseJsonFromMemory完成:

int32_t JsonParser::ParseJsonFromMemory( const char* dumpConfigData, size_t dumpConfigSize, nlohmann::json& js, std::string& errMsg) { errMsg.clear(); if ((dumpConfigData == nullptr) || (dumpConfigSize == 0U)) { errMsg = "Invalid input parameters"; IDE_LOGD("Parse json from memory failed: invalid input parameters."); return ADUMP_INPUT_FAILED; } try { std::string_view jsonString(dumpConfigData, dumpConfigSize); IDE_LOGI("Parse json string: %.*s", static_cast<int>(jsonString.size()), jsonString.data()); js = nlohmann::json::parse(jsonString); IDE_LOGD("Parse json successfully."); return ADUMP_SUCCESS; } catch (const nlohmann::json::parse_error& e) { errMsg = e.what(); IDE_LOGE("JSON parse error: %s", e.what()); } catch (const std::exception& e) { errMsg = e.what(); IDE_LOGE("Unexpected error while parsing JSON from memory: %s", e.what()); } return ADUMP_INPUT_FAILED; }

关键实现细节:

  • 使用nlohmann/json库的nlohmann::json::parse对配置内存数据进行解析,这与报错示例中的json.exception.type_error.302异常前缀完全吻合;
  • 配置数据为空(空指针或长度为 0)时,errMsg被置为Invalid input parameters
  • 捕获nlohmann::json::parse_error(纯语法错误)和其他std::exception(运行时异常,如类型错误),异常描述e.what()会原样写入errMsg,作为 EP0004 报错的 Reason 部分透传出来。

3. 错误上报入口:DumpConfigConverter::Convert

dump_config_converter.cpp 中的Convert是 Dump 配置转换的主流程,也是 EP0004 仅有的两处上报点:

上报点 1:JSON 语法解析失败

nlohmann::json js; std::string errMsg; needDump = false; int32_t ret = JsonParser::ParseJsonFromMemory(dumpConfigData_, dumpConfigSize_, js, errMsg); if (ret != ADUMP_SUCCESS) { REPORT_EP0004_PARSE_ERROR("Convert", errMsg, configPath_); return ADUMP_FAILED; }

ParseJsonFromMemory返回失败时,立即上报 EP0004,Reason 即为解析器返回的errMsg,随后整个配置转换流程以失败结束。

上报点 2:后续处理中的运行时异常

try { ... dumpJs_ = js.at(ADUMP_DUMP); ... } catch (const std::exception& e) { REPORT_EP0004_PARSE_ERROR("Convert", std::string(e.what()), configPath_); return ADUMP_FAILED; }

即使在语法解析通过之后,若对 JSON 内容的后续访问(如js.at(ADUMP_DUMP)取值、类型转换等)抛出std::exception(典型的如官方示例中的type_error.302:期望数组实际是字符串),同样会走 EP0004 上报路径。

由此可以归纳出触发 EP0004 的完整条件:Dump 配置文件在语法或底层类型层面无法被 nlohmann/json 正常解析/访问。而字段语义层面的校验(如dump必须是对象、dump_list必须是数组等)则走 EP0001 路径,两者在源码中分工明确。

典型报错场景与原因分类

结合 单元测试用例TestJsonSyntaxErrors,EP0004 覆盖的典型失败场景包括:

输入配置(JSON)问题描述期望错误码
{"dump": {"dump_op_switch": "on"花括号未闭合,JSON 语法不完整EP0004
{"dump": {"dump_list": [{"model_name": "model1"})方括号/圆括号混用、括号不匹配EP0004
asdf{完全不是合法 JSONEP0004

测试辅助函数TestFailureHelper(同文件)会构造DumpConfigConverter并调用Convert,断言返回值为ADUMP_FAILED且上报的错误码正是EP0004

void TestFailureHelper( const std::string& configData, const std::string& configPath, const std::string& expectedErrorCode) { ... DumpConfigConverter converter{configData.c_str(), configData.size(), configPath.c_str()}; int32_t ret = converter.Convert(dumpType, dumpConfig, IsNeedDump, dumpDfxConfig); EXPECT_EQ(ret, ADUMP_FAILED); EXPECT_FALSE(IsNeedDump); EXPECT_EQ(GetLastReportedErrorCode(), expectedErrorCode); }

需要注意的是,同一测试文件中另有TestDumpFieldTypeErrors(L483-L492),其中{"dump": true}{"dump": []}语法合法但类型错误的输入期望的是 EP0001 而非 EP0004。这说明:凡是能通过 JSON 语法解析的问题,都不会报 EP0004;EP0004 严格对应"文件本身无法被解析"这一层。

排查与修复步骤

按照官方文档的解决方法,修复思路是按照 Reason 中的提示检查并修改。结合源码实现,可以细化出以下排查路径:

步骤 1:先读 Reason,区分错误大类

EP0004 报错中的 Reason 直接来自 nlohmann/json 的异常描述,常见形态包括:

  • [json.exception.parse_error.101] parse error at line X, column Y: ...—— 纯语法错误,通常是括号不匹配、引号未闭合、尾逗号、非法字符等;
  • [json.exception.type_error.302] type must be array, but is string—— JSON 合法,但代码期望的 JSON 类型与实际类型不一致(如官方示例);
  • Invalid input parameters—— 配置文件内容为空(空指针或长度为 0)。

步骤 2:检查 JSON 语法与括号配对

对配置文件做基本的语法自查:

  • 花括号{}、方括号[]、引号必须成对且闭合;
  • 键名必须用双引号包裹;
  • 不允许尾随逗号(如"a": 1,});
  • 整体必须是单个合法的 JSON 值(对象或数组)。

仓库中的合法示例可参考 0_adump_args/acl.json:

{"dump": {"dump_path": "./", "dump_list": [], "dump_op_switch": "on", "dump_data": "tensor"}}

步骤 3:核对配置项取值是否匹配期望类型

当 Reason 中出现type_error时,说明 JSON 语法虽合法,但某个字段的类型与解析代码期望不符。adump 解析代码(dump_config_converter.cpp)对dump对象内各字段的读取方式决定了其期望类型:字符串型字段直接取值,而dump_statsdump_listblacklistpos等字段则要求为字符串数组。类型不匹配会抛异常并触发 EP0004。

步骤 4:确认整体结构

配置文件的顶层应包含dump对象(ADUMP_DUMP键),Dump 配置项均位于该对象内。若缺失dump键,Convert会直接返回成功而不做 Dump,不会触发 EP0004。

步骤 5:修改后重跑验证

修正配置后重新触发采集,确认不再出现Failed to parse file ...报文。若解析通过后仍有问题,报错码会切换为 EP0001(字段类型/内容)、EP0002(取值不在期望集合内)、EP0003(取值非法并给出原因)或 EP0005(配置项冲突),此时需参照对应错误码文档继续排查。

与其他 EP 错误码的边界区分

在实际排障中,最容易与 EP0004 混淆的是 EP0001,二者的边界如下:

  • EP0004:文件整体无法解析(JSON 语法错误、解析期类型异常、内容为空)。对应ParseJsonFromMemory失败或Converttry块内抛出的std::exception
  • EP0001:文件能解析,但配置项的类型或内容非法(如dump不是对象、dump_path不是字符串),由CheckDumpFieldTypesCheckDumpFieldValues等校验函数主动上报,Reason 来自 adump_error_manager.h 中预定义的常量(如This configuration item must be of the array typeThe configuration item value is empty等);
  • EP0005:文件能解析且字段合法,但配置项之间存在互斥约束冲突,Reason 模板同样定义在 adump_error_manager.h 中。

简单记忆:EP0004 是"JSON 都读不了",EP0001/0002/0003/0005 是"JSON 读得了但内容不合法"

测试验证与进一步阅读

若希望复现 EP0004 的上报行为,可直接查看 dump_config_converter_utest.cpp 中的TestJsonSyntaxErrors用例;其错误码模板与参数格式化逻辑在 error_manager_stub.cpp 中有对应桩实现,可供理解上报机制的端到端行为。

进一步阅读建议:

  • EP0004 官方文档(英文)
  • EP0004 官方文档(中文)
  • Dump 错误码索引
  • 错误码注册表
  • EP0004 上报宏与错误原因常量
  • Dump 配置转换主流程
  • JSON 解析器实现

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

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

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询