CANN oam-tools asys coretrace 文件解析:命令详解、addr2line 符号化原理与故障定位实战

CANN oam-tools asys coretrace 文件解析:命令详解、addr2line 符号化原理与故障定位实战 CANN oam-tools asys coretrace 文件解析命令详解、addr2line 符号化原理与故障定位实战【免费下载链接】oam-tools本项目为开发者提供故障定位工具包含故障信息收集软硬件信息展示AI core error报错分析等能力提升故障问题定位效率文档可在昇腾社区搜索“故障处理简介”选择社区版。项目地址: https://gitcode.com/cann/oam-tools本文聚焦 CANN oam-tools 项目中 asys 工具的核心分析能力之一coretrace 文件解析。文章围绕asys analyze -rcoretrace的命令格式、全部参数语义、解析输出格式展开并结合仓库源码说明其基于 addr2line 的符号化解析原理、动态库检索策略与多线程批处理实现。读完本文你将能够在发生 Device 侧进程异常退出如 Signal 11时独立完成 coretrace 文件的获取、解析与堆栈解读并具备排查解析结果异常如出现?或行号偏差的实战能力。功能说明什么是 coretrace 文件解析coretrace 是 Device 侧系统类日志中的一种维测信息文件当 Device 侧进程发生异常例如段错误触发 Signal 11时系统会记录下当时的崩溃信号、线程信息以及各线程的调用栈帧地址形成coretrace.*格式的原始文件。这类文件中的栈帧只有原始地址无法直接阅读需要结合对应的动态库二进制才能还原出函数名与源代码行号。asys 工具的 coretrace 解析功能即用于完成这一还原过程以 coretrace 文件为输入解析其中每个线程的调用栈将原始地址转换为“地址 函数名 二进制名”的可读堆栈供后续故障定位使用。该能力与 asys 的stackcore 文件解析、coredump 文件解析共同构成 asys 的堆栈类分析家族且三者共享asys analyze命令框架与--symbol_path符号检索机制。从仓库结构看coretrace 解析功能主要由 coretrace_collect.py 中的ParseCoreTrace类实现并通过 asys_analyze.py 中的AsysAnalyze统一调度。关于 asys 工具的完整功能清单与使用约束可参见 asys 工具功能及约束。coretrace 文件的获取方式coretrace 文件属于 Device 侧系统类日志和维测信息一般通过以下途径获取使用 Device 侧日志导出工具如 msnpureport 工具执行“单次导出 Device 侧系统类日志和其他维测信息”操作导出 coretrace 文件通过 asys 自身的故障信息收集功能进行收集收集到的日志信息中包含 coretrace 文件该场景下 coretrace 文件收集需要 root 权限具体权限要求参见asys 工具功能及约束中的信息收集列表。获取到 coretrace 文件后即可使用本文介绍的解析命令将其转换为可读堆栈。使用前提与注意事项使用 coretrace 解析功能前请先确认以下前提条件否则可能导致解析失败或结果不准确依赖 addr2line 工具coretrace 解析功能依赖 Linux 系统自带的addr2line工具进行堆栈函数名和行号的解析。请确保addr2line已安装且执行该脚本的用户有权限执行它。若工具缺失asys 会直接报错退出。这一点与 stackcore 解析不同stackcore 依赖readelf和addr2line两个工具coretrace 解析只依赖addr2line。在获取 coretrace 文件的环境中执行解析需在获取 coretrace 文件即发生故障的环境中执行 coretrace 文件解析命令否则可能因动态库版本不匹配导致解析结果不准确。芯片形态支持限制仅 Ascend 950PR / Ascend 950DT 支持使用 coretrace 文件解析功能Atlas A3 训练系列产品 / Atlas A3 推理系列产品、Atlas A2 训练系列产品 / Atlas A2 推理系列产品不支持使用 coretrace 文件解析功能Atlas 200I/500 A2 推理产品、Atlas 推理系列产品、Atlas 训练系列产品不支持使用 coretrace 文件解析功能。环境形态限制asys 工具整体仅支持在 Ascend EP 形态下使用参见asys 工具功能及约束coretrace 解析作为analyze子命令同样遵循该约束。从源码实现看ParseCoreTrace.check_tool_exists()会通过check_command(addr2line)校验工具是否存在不存在时记录错误日志并返回失败对应日志The addr2line tool does not exist, install it before using it.。仓库中的单元测试 test_asys_analyze.py 也覆盖了该场景test_asys_analyze_coretrace_no_addr2line验证了工具缺失时解析会失败并输出上述提示。命令格式coretrace 解析支持两种输入方式解析单个文件或解析整个目录含子目录下的多个文件。方式一解析单个文件asys analyze -rcoretrace --filefilename --symbol_pathpath1,path2 --outputpath3方式二解析指定目录下的多个文件asys analyze -rcoretrace --pathdirectory --symbol_pathpath1,path2 --outputpath3两种方式中--file与--path只能选择其一不能同时存在。从命令行解析器的源码看analyze子命令将--file与--path定义在add_mutually_exclusive_group互斥组中argparse 层面即禁止二者同时出现且二者均通过ArgChecker.FILE_PATH_EXIST_R校验路径是否存在。参数说明coretrace 解析涉及的全部参数如下表所示参数必选/可选说明r必选解析模式此处设置为coretrace用于解析 coretrace 格式的文件coretrace.*文件供后续定位使用。filecoretrace 模式下必选用于解析单个文件此处设置为包含路径的文件名。与path互斥。pathcoretrace 模式下必选指定目录用于解析指定目录及其子目录下的多个文件。与file二选一两者不能同时存在。symbol_path可选coretrace 模式解析所需要的动态库目录可传多个目录用逗号隔开。symbol_path只扫描当前目录下的动态库按路径 1、路径 2 的顺序查找不扫描子目录为防止误解析建议将相关动态库放在同一个路径下。不指定时从 coretrace 文件中获取所需要的动态库路径为防止找不到动态库文件建议仅在发生 coredump 错误的环境上使用该方式。output可选其值作为 asys 工具的结果输出目录的路径前缀最终输出目录为{output}/asys_output_timestamp。命令行中不带output参数时输出结果存放在命令行执行目录下若output指定值为空、无效字符串、或指定路径目录无写权限、或创建目录失败则 asys 工具退出执行并报错。关于symbol_path的检索逻辑源码中有更精确的说明ParseCoreTrace.get_binary_path()会提取 coretrace 文件中二进制路径的文件名bin_name_path.split(/)[-1]然后依次在每个symbol_path目录下拼接该文件名并检查是否存在命中即返回全部未命中时会发出警告日志xxx is not exists.。因此目录层级较深或不在此目录下的动态库无法被命中这也是文档建议“将相关动态库放在一个路径下”的原因。需要特别说明的是symbol_path参数在仓库的参数定义中同时被stackcore与coretrace两种模式共用官方 help 文本中标注“仅对 stackcore 有效”属于历史注释实际 coretrace 解析路径__atrace_analyze中ParseCoreTrace(self.symbol_path, self.file)同样会读取该参数未设置时 asys 会提示--symbol_path is not set, the default path will be used to analyze.并回退到 coretrace 文件内记录的动态库路径。使用示例以下示例解析单个 coretrace 文件指定两个动态库搜索目录并将结果输出到$HOME/dfx_info前缀目录下asys analyze -rcoretrace --filecoretrace.log-daemon.12335.11.1749181305 --symbol_path$HOME/test1,$HOME/test2 --output$HOME/dfx_info批量解析目录场景示例asys analyze -rcoretrace --path$HOME/dfx_logs --symbol_path$HOME/libs --output$HOME/dfx_info执行成功后解析结果将写入{output}/asys_output_timestamp目录。解析过程中单文件模式下 asys 会先将被解析文件拷贝到输出目录再在原路径位置进行解析目录模式下仅会拷贝文件名以coretrace开头的文件见 asys_analyze.py 中__copy_dir的过滤逻辑因此目录中混入的其他类型文件不会被误处理。解析输出说明解析后的文件示例如下Signal 11 pid 12335 PID 12335 TGID 12335 comm log-daemon 0xdfffcac78a68 0x00000000000b4a68: clock_nanosleep at ??:? /usr/lib64/libc.so.6 0xdfffcac7dc4c 0x00000000000b9c48: __nanosleep at ??:? /usr/lib64/libc.so.6 0xdfffcaca6d88 0x00000000000e2d84: usleep at ??:? /usr/lib64/libc.so.6 0xaaaad1e22dec 0x0000000000012de8: ToolSleep at log_system_api.c:704 /var/log-daemon 0xaaaad1e1cb58 0x000000000000cb54: main at log_daemon.c:217 /var/log-daemon 0xdfffcabef040 0x000000000002b03c: __libc_init_first at ??:? /usr/lib64/libc.so.6 0xdfffcabef118 0x000000000002b114: __libc_start_main at ??:? /usr/lib64/libc.so.6 0xaaaad1e1c680 0x000000000000c67c: $x at start.os:? /var/log-daemon PID 12356 TGID 12335 comm adx_get_file_th 0xdfffcaca550c 0x00000000000e150c: ioctl at ??:? /usr/lib64/libc.so.6 0xdfffcbc413fc 0x00000000000543f8: HiIam::AppIoctl(int, unsigned long, void*, unsigned int, bool) at ??:? /usr/lib64/libiam.so.0.1.0.0 0xdfffcbc415ec 0x00000000000545e8: ioctl at ??:? /usr/lib64/libiam.so.0.1.0.0 0xdfffcb2d61ec 0x000000000006f1e8: mmIoctl at hdc_pcie_drv.c:? /usr/lib64/libascend_hal.so 0xdfffcb2d678c 0x000000000006f788: hdcIoctl at hdc_pcie_drv.c:? /usr/lib64/libascend_hal.so 0xdfffcb2d8550 0x000000000007154c: hdcPcieEpollWait at ??:? /usr/lib64/libascend_hal.so 0xdfffcb2dabf4 0x0000000000073bf0: drvHdcPcieEpollWait at hdc_pcie_epoll.c:? /usr/lib64/libascend_hal.so 0xdfffcb2da7f4 0x00000000000737f0: drvHdcEpollWait at ??:? /usr/lib64/libascend_hal.so 0xaaaad1e6dc60 0x000000000005dc5c: Adx::AdxHdcEpoll::EpollWait(std::vectorAdx::EpollEvent, std::allocatorAdx::EpollEvent , int, int) at ??:? /var/log-daemon 0xaaaad1e6c51c 0x000000000005c518: Adx::AdxServerManager::ComponentWaitEvent() at :? /var/log-daemon 0xaaaad1e6c780 0x000000000005c77c: Adx::AdxServerManager::Run() at ??:? /var/log-daemon 0xaaaad1e6ea0c 0x000000000005ea08: Adx::Runnable::Process(void*) at ??:? /var/log-daemon 0xdfffcac46168 0x0000000000082164: pthread_condattr_setpshared at ??:? /usr/lib64/libc.so.6 0xdfffcacad8dc 0x00000000000e98d8: clone at ??:? /usr/lib64/libc.so.6 ......输出格式解读文件首行为崩溃信号信息格式为Signal 信号号 pid 进程号例如Signal 11 pid 12335表示进程因 Signal 11SIGSEGV段错误而崩溃。每个线程的堆栈以PID pid TGID tgid comm 线程名开头其中PID为线程号TIDTGID为线程组 IDcomm为线程名。示例中第二个线程PID 12356 TGID 12335 comm adx_get_file_th属于进程 12335 的一个子线程。每个栈帧按{地址} {函数名} {二进制名}三段式格式输出例如0xdfffcac78a68 0x00000000000b4a68: clock_nanosleep at ??:? /usr/lib64/libc.so.6其中第一列为崩溃环境中的运行时地址对应 coretrace 原始文件中的帧指针fp第二列是相对于动态库加载基址的偏移量即fp - start_addr - shift换算出的地址随后是该地址解析出的函数名与源码位置函数名 at 文件:行号最后一列为所属动态库文件。解析出的ToolSleep at log_system_api.c:704、main at log_daemon.c:217等行即为故障定位中最有价值的业务函数调用点。若函数名获取失败则该位置显示解析过程中自动计算出来的十六进制偏移值。此时需检查symbol_path配置目录是否正确以及该目录下的动态库文件是否正确。解析原理从源码看 addr2line 符号化调用链coretrace 解析的核心实现在 coretrace_collect.py 的ParseCoreTrace类中其整体调用链为格式与前置校验start_parse_file()首先校验文件名是否以coretrace开头否则报错The xxx file is not in coretrace format.随后校验addr2line是否存在、文件是否为空。内存映射表构建parse_line()逐行扫描 coretrace 文件解析形如start-end的地址区间行按二进制名归并出内存映射表maps同一二进制出现多个区间时取最小起始地址与最大结束地址同时解析Signal、PID等元信息跳过[0]、(deleted)及uburma、davinci_manager相关噪声行。地址换算与符号化对于每个栈帧地址fpparse_addr_src_line()在映射表中定位其所属二进制与加载区间计算相对偏移delta hex(fp - start_addr - shift)其中shift依据帧编号取值#0帧为 0其余帧为 4然后构造 addr2line 命令执行符号化cmd [self.__addr2line, -Cifps, -e, bin_path, -a, delta]其中各选项含义为-C关闭/开启 demangleC 符号还原为可读形式如示例中的Adx::AdxHdcEpoll::EpollWait(...)、-i内联函数展开、-f输出函数名、-p美化输出、-s只显示源文件名。命令执行结果即为“函数名 at 文件:行号”文本。异常兜底若 addr2line 执行失败捕获OSError、ValueError或输出为空则回退输出自动计算的十六进制偏移并记录警告日志。目录批量解析的多线程实现使用--path解析目录时ParseCoreTrace.run()通过walk_dir递归收集目录及子目录下所有文件并为每个文件启动一个守护线程执行解析见save_file_result与线程列表threads全部线程结束后统一汇总结果。因此批量解析大量 coretrace 文件时具备一定的并发能力单文件解析则会通过out_progress_bar显示解析进度。测试用例印证仓库单元测试 test_asys_analyze.py 对 coretrace 解析进行了较完整的覆盖可作为理解行为边界的参考test_asys_analyze_coretrace/test_asys_analyze_coretrace_with_binary验证单文件解析及配合symbol_path指定动态库目录的解析流程test_asys_analyze_coretrace_run_addr2line_failed验证 addr2line 执行抛出OSError时解析仍可容错完成test_asys_analyze_coretrace_no_addr2line验证 addr2line 缺失时解析失败并输出对应错误日志test_asys_analyze_coretrace_dir验证--path目录模式解析test_asys_analyze_coretrace_other_file/test_asys_analyze_coretrace_empty_file验证非 coretrace 格式文件与空文件的报错处理test_asys_analyze_path_output_same验证--output与--path指向同一目录时工具报错退出对应 asys_analyze.py 中 “The output directory cannot be the same as the path directory or its subdirectories.” 的校验逻辑。常见问题与排查建议1. 解析结果中出现?字符解析后的文件如果存在?字符如??:?、at ??:?可能由以下原因导致编译选项问题该动态库文件编译时没有使用-g选项导致文件中未保留调试信息DWARF 调试段addr2line 无法定位到行号未添加链接参数未使用-rdynamic通知链接器将所有符号添加到动态符号表中导致动态符号表缺失部分符号未找到动态库symbol_path目录中未找到相匹配的动态库或动态库版本与发生故障时不一致。排查建议优先核对symbol_path是否指向了包含正确动态库的目录、目录下动态库是否与故障环境一致对于自研二进制确认其编译时开启了-g并添加了-rdynamic。2. 解析出的行号存在少许偏差coretrace 解析函数名和行号时部分动态库解析出的行号会有少许偏差原因如下编译选项不同的编译选项特别是与调试信息相关的选项可能会造成影响优化级别较高的优化级别如-O2、-O3可能会导致代码的重组和优化内联、指令重排等从而使行号与原始源代码的对应关系发生偏差。排查建议此类偏差属于编译优化带来的正常现象定位时以函数名为主、行号作为参考即可若需精确行号可尝试使用带调试信息且优化级别较低如-O0 -g的构建版本配合解析。3. 解析失败或结果为空确认addr2line已安装且当前用户有执行权限确认解析环境与获取 coretrace 文件的环境一致确认--file与--path未同时指定二者互斥确认--output指向的目录存在且可写无写权限时 asys 会退出并报错确认输入文件确实是 coretrace 格式文件名以coretrace开头且非空。与 asys 其他文件解析能力的关系在 asys 的 analyze 体系中coretrace 解析与另外两种堆栈解析能力互补使用可形成完整的故障定位链路解析模式输入文件依赖工具输出coredump系统 core 文件gdbstackcore 格式的 txt 文件stackcorestackcore 格式 txt 文件readelf、addr2line可读堆栈Thread n (tid, name)格式coretracecoretrace 格式文件coretrace.*addr2line可读堆栈PID x TGID y comm z格式coredump 解析coredump 文件解析可先借助 gdb 将 core 文件转为 stackcore 格式 txtstackcore 解析stackcore 文件解析再进一步将其符号化为可读堆栈而 coretrace 解析则直接面向 Device 侧导出的 coretrace 原始文件一步到位完成符号化。三者共享--symbol_path、--output等参数语义与asys analyze命令框架掌握 coretrace 解析即可触类旁通其余两种模式的用法。总结coretrace 文件解析是 asys 工具在 Device 侧进程异常场景下的关键维测能力一条asys analyze -rcoretrace命令即可将原始崩溃栈帧还原为带函数名与行号的可读堆栈。实际使用时请重点把握三点确保addr2line可用并在故障环境执行解析、通过--symbol_path精确指定与故障环境一致的动态库目录、结合输出中的?与行号偏差现象反向检查动态库与编译选项。更完整的 asys 使用指导可参阅 asys 工具使用指导故障信息收集与权限要求参见故障信息收集与asys 工具功能及约束。【免费下载链接】oam-tools本项目为开发者提供故障定位工具包含故障信息收集软硬件信息展示AI core error报错分析等能力提升故障问题定位效率文档可在昇腾社区搜索“故障处理简介”选择社区版。项目地址: https://gitcode.com/cann/oam-tools创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考