ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

CANN opbase 错误码 EZ1011(Invalid_Argument_Null_Pointer)空指针参数校验与排查指南

CANN opbase 错误码 EZ1011(Invalid_Argument_Null_Pointer)空指针参数校验与排查指南 CANN opbase 错误码 EZ1011Invalid_Argument_Null_Pointer空指针参数校验与排查指南【免费下载链接】opbase本项目是CANN算子库的基础框架库为算子提供公共依赖文件和基础调度能力。项目地址: https://gitcode.com/cann/opbase本文面向在 CANN opbase 框架上开发、调试或调用算子执行接口的开发者系统讲解 Nnopbase Errors 错误类别下错误码EZ1011Invalid_Argument_Null_Pointer的完整含义错误消息的占位符结构、在仓库源码中的注册与触发链路、典型触发场景如NnopbaseRunWithWorkspace传入空 executor以及可复现、可验证的排查与修复步骤。读完本文你将能根据一条... cannot be a NULL pointer.报错快速定位到具体接口与参数并理解该错误码在 nnopbase_error_msg.h 与错误码注册 JSON 中的底层实现。错误码速览EZ1011 在官方错误码清单 Nnopbase-Errors.md 中与 EZ1001EZ1014 一并归档属于Nnopbase Errors算子库基础框架错误类别。从错误码注册表 op_error_manager.cpp 中的 JSON 定义可以确认其完整元信息字段取值errClassNnopbase ErrorserrTitleInvalid_Argument_Null_PointerErrCodeEZ1011ErrMessage%s failed because %s cannot be a NULL pointer.ArglistfunctionName, paraNamesuggestionPossible Cause: N/ASolution: N/A需结合具体报错定位该错误码专门用于标识某个算子执行接口的参数被传入了 NULL 指针属于参数类Invalid Argument错误通常在接口入口的参数校验阶段即被抛出而不会进入后续的算子调度与执行流程。错误信息格式详解EZ1011 的报错格式为%s failed because %s cannot be a NULL pointer.两个占位符%s的语义按顺序为接口名functionName发生空指针校验失败的 API 名称参数名paraName被判定为 NULL 的具体参数名称。官方文档给出的报错示例如下NnopbaseRunWithWorkspace failed because executor cannot be a NULL pointer.逐段解析这条报错接口为NnopbaseRunWithWorkspace算子第二阶段执行接口参数为executor算子执行器句柄。整条消息的含义是调用NnopbaseRunWithWorkspace时传入的executor为 NULL而该参数不允许为 NULL。对应中文版文档见 docs/zh/error_code/Nnopbase-Errors/EZ1011-Invalid_Argument_Null_Pointer.md两者语义完全一致。源码级实现错误码如何被抛出EZ1011 的生成逻辑集中在两处源码理解它们即可掌握该错误码的完整调用链。1. 消息构造宏src/nnopbase/common/inc/nnopbase_error_msg.h 中定义了消息构造宏#define OP_LOGE_FOR_INVALID_ARGUMENT_NULL_POINTER(functionName, paraName) \ do { \ std::string msg std::string(functionName) failed because paraName cannot be a NULL pointer.; \ const std::vectorconst char* msgKey {functionName, paraName}; \ const std::vectorconst char* msgValue {functionName, paraName}; \ OP_LOGE_WITHOUT_REPORT(EZ1011, %s, msg.c_str()); \ REPORT_PREDEFINED_ERR_MSG(EZ1011, msgKey, msgValue); \ } while (false)可以看到宏内部做了两件事用functionName failed because paraName cannot be a NULL pointer.拼接出与文档一致的完整消息文本以{functionName, paraName}为键、实际传入的字符串为值调用REPORT_PREDEFINED_ERR_MSG(EZ1011, msgKey, msgValue)上报预定义错误消息与注册表中的Arglist一一对应。2. 通用空指针断言宏同文件 nnopbase_error_msg.h 还提供了配套的断言宏供各接口做统一入口校验#define NNOPBASE_ASSERT_NULLPTR_WITH_RETURN(x, ret) \ do { \ if ((x) nullptr) { \ OP_LOGE_FOR_INVALID_ARGUMENT_NULL_POINTER(__func__, #x); \ return (ret); \ } \ } while (false)该宏的语义是若表达式x为空指针则以当前函数名__func__作为接口名、以参数名的字符串形式#x作为参数名触发 EZ1011 日志上报并立即返回指定的错误码ret。#x的字符串化机制保证了报错中的参数名与代码中的变量名完全一致便于开发者对照源码排查。值得一提的是nnopbase_error_msg.h 头部注释虽标注为 ERROR MSG FOR NNOPBASE (EZ1002-EZ1009)实际文件内已扩展覆盖至 EZ1014含 EZ1011从源码结构看该注释存在滞后。3. 错误码注册表op_error_manager.cpp 通过REG_FORMAT_ERROR_MSG将上表 JSON 注册为框架可识别的错误码描述保证上层日志与错误上报工具能够按EZ1011索引到Invalid_Argument_Null_Pointer的标题与消息模板。典型触发场景NnopbaseRunWithWorkspace文档示例中的NnopbaseRunWithWorkspace是 CANN opbase 算子执行第二阶段接口声明于 individual_op_api.hVISIBILITY_EXPORT aclnnStatus NnopbaseRunWithWorkspace(void* executor, aclrtStream stream, void* workspace, uint64_t workspaceLen);其实现位于 individual_op_api.cpp入口处对空指针做了显式校验aclnnStatus NnopbaseRunWithWorkspace(void* executor, aclrtStream stream, void* workspace, uint64_t workspaceLen) { if (executor nullptr) { OP_LOGE_FOR_INVALID_ARGUMENT_NULL_POINTER(Calling the second-phase API of aclnn, executor); return ACLNN_ERR_PARAM_NULLPTR; } if (workspaceLen 0U workspace nullptr) { OP_LOGE_FOR_INVALID_ARGUMENT_NULL_POINTER(Calling the second-phase API of aclnn, workspace); return ACLNN_ERR_PARAM_NULLPTR; } ... }由此可以总结出该接口触发 EZ1011 的两种典型情况executor 为 NULLexecutor是第一步创建的执行器句柄正常情况下应来自NnopbaseCreateExecutor等创建接口的返回值。若创建失败未被检查、或句柄被错误释放后仍继续调用就会命中第一处校验workspace 为 NULL 且 workspaceLen 0当算子实际需要工作区workspace时调用方必须传入非空的工作区指针若workspaceLen大于 0 而workspace为空同样触发 EZ1011 并返回ACLNN_ERR_PARAM_NULLPTR。注意文档示例中functionName占位符显示为NnopbaseRunWithWorkspace而源码当前实现传入的是Calling the second-phase API of aclnn。两者均是对“调用第二阶段 aclnn API”的表述说明该占位符由调用点按语义传入同一错误码可被不同接口复用——这正是 EZ1011 作为通用空指针参数错误码的设计意图。其他调用点与返回码约定NNOPBASE_ASSERT_NULLPTR_WITH_RETURN宏在仓库中被广泛使用触发 EZ1011 时返回的错误码因场景而异在 acl_op_api.cpp 等通用算子 API 入口对tensor、executor等参数判空后返回ACLNN_ERR_INNER_NULLPTR在 individual_op_api.cpp 等独立算子接口中对executor、attrAddr、attrLen等判空后返回ACLNN_ERR_PARAM_NULLPTR在 indv_executor.cpp 等执行器内部同样使用该宏做二次防护。从源码结构可以推断EZ1011 日志用于错误定位与信息上报而接口的实际返回值由各调用点通过ret参数指定。排查时除了阅读日志还应关注接口返回值两者结合即可确认是参数空指针问题。排查与解决方法根据文档给出的解决方案——Please adjust the parameter value as prompted in the error message请根据报错提示调整参数值完整的排查流程建议如下读取报错中的参数名从%s failed because %s cannot be a NULL pointer.中提取第二个%s即paraName确定是哪个参数为空核对参数来源若参数是句柄类如executor检查其是否由对应的创建接口正确返回、是否在调用前被释放或覆盖若参数是缓冲区类如workspace、addr确认在workspaceLen 0时已通过NnopbaseRunForWorkspace等接口查询所需大小并完成内存分配若参数是描述符类如tensor、tensors、attrAddr确认相关对象创建成功后再传入修正调用代码为报错参数传入合法、非空的指针后重新运行回归验证可通过单元测试用例快速复现与验证见下文。测试用例验证仓库在 tests/nnopbase/ut/individual_op/api_utest.cpp 中提供了针对该错误码的回归测试size_t workspaceLen 0U; ASSERT_EQ(NnopbaseRunForWorkspace(executor, workspaceLen), ACLNN_ERR_PARAM_NULLPTR); void* stream nullptr; void* workspace nullptr; void* handle executor; ASSERT_EQ(NnopbaseRunWithWorkspace(handle, stream, workspace, workspaceLen), ACLNN_ERR_PARAM_NULLPTR);该用例故意构造空指针参数调用NnopbaseRunWithWorkspace并断言返回值等于ACLNN_ERR_PARAM_NULLPTR与 individual_op_api.cpp 的校验逻辑相互印证。同一测试文件中还有大量针对executor、tensors等参数判空的用例如acl_op_api.cpp对应的 UT可作为排查空指针问题的参考范本。小结EZ1011Invalid_Argument_Null_Pointer是 CANN opbase 框架在接口入口统一拦截空指针参数的标准错误码消息模板%s failed because %s cannot be a NULL pointer.中的两个占位符分别对应接口名与参数名。遇到该报错时只需按报错中的参数名回溯其创建与传递链路补上合法指针或修正参数组合即可解决。若要深入理解其内部机制可依次阅读消息构造宏 nnopbase_error_msg.h、错误码注册表 op_error_manager.cpp 以及接口校验实现 individual_op_api.cpp。完整的 Nnopbase Errors 错误码目录见 Nnopbase-Errors.md。【免费下载链接】opbase本项目是CANN算子库的基础框架库为算子提供公共依赖文件和基础调度能力。项目地址: https://gitcode.com/cann/opbase创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表