ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

Erlang/OTP Crashdump Viewer(cdv)使用指南:从崩溃转储到问题定位的可视化分析

Erlang/OTP Crashdump Viewer(cdv)使用指南:从崩溃转储到问题定位的可视化分析 Erlang/OTP Crashdump Viewercdv使用指南从崩溃转储到问题定位的可视化分析【免费下载链接】otpErlang/OTP项目地址: https://gitcode.com/gh_mirrors/ot/otp导读本文介绍 Erlang/OTP Observer 应用中的Crashdump Viewer命令行入口为cdv——一个基于 WxWidgets 的图形化工具用于浏览和分析 Erlang 运行时系统生成的崩溃转储crashdump文件。当 BEAM 虚拟机因内存耗尽、进程异常或其他致命错误而崩溃时它会留下一个文本格式的erl_crash.dump其中记录了进程、端口、ETS 表、定时器、调度器、原子表等海量原始信息手动解析这些原始文件非常繁琐Crashdump Viewer 则将它们组织成带索引的图形界面帮助开发者快速定位崩溃原因。读完本文你将掌握cdv的三种启动方式、主窗口各信息标签页的含义与用法、通用字段语义以及各标签页背后的解析实现与测试验证方式。什么是 Crashdump ViewerCrashdump Viewer 是 Observer 应用lib/observer的一部分核心实现位于 crashdump_viewer.erl其模块文档明确描述为 A WxWidgets based tool for browsing Erlang crashdumps并直接链接到本文对应的官方用户指南。从源码结构看Crashdump Viewer 由两类模块协作完成服务端后端crashdump_viewer.erl 是一个gen_server负责读取并索引 crashdump 文件GUI 前端cdv_wx主窗口见 cdv_wx.erl、cdv_table_wx、cdv_virtual_list_wx等负责渲染以及一组按数据类别划分的回调模块cdv_gen_cb、cdv_proc_cb、cdv_port_cb、cdv_ets_cb、cdv_timer_cb、cdv_sched_cb、cdv_fun_cb、cdv_atom_cb、cdv_dist_cb、cdv_mod_cb、cdv_mem_cb、cdv_int_tab_cb、cdv_persistent_cb等它们分别负责渲染各标签页内容。这些模块全部登记在 observer.app.src 的modules列表和 src/Makefile 中编译产物随 Observer 应用一起发布。快速上手三种启动方式Crashdump Viewer 可以从操作系统命令行、Erlang 节点或 Windows 批处理三种方式启动。1. 使用cdv脚本推荐最简单的方式是调用 Observer 应用priv目录下的cdvshell 脚本并把 crashdump 的完整路径作为参数传入cdv /path/to/erl_crash.dump该脚本位于 Observer 应用的priv目录安装后位于$ERL_TOP/lib/observer-*/priv。如果省略文件名参数则会弹出文件选择对话框由用户在文件系统中挑选要加载的 dump 文件。在 Windows 平台上使用同目录下的批处理脚本cdv.bat。cdv脚本的用法同样记录在 cdv_cmd.md 中其命令行语法为cdv [file]参数file可选省略时弹出文件对话框。从源码看脚本启动最终调用的是 crashdump_viewer.erl 中的script_start/0、script_start/1和do_script_start/1。script_start([FileAtom])会先用filelib:is_regular/1校验文件是否存在不存在时输出错误信息cdv error: the given file does not exist并打印用法usage: cdv [file] The file must be an existing erlang crash dump. If omitted a file dialog will be opened.加载成功后do_script_start/1会将当前进程与cdv_wx进程链接link/1并等待其退出若 GUI 进程异常退出则输出cdv crash: Reason。这也是cdv脚本能保持在前台、随 GUI 关闭而退出的原理。2. 从 Erlang 节点启动在已运行的 Erlang 节点中可以调用crashdump_viewer:start(). % 打开文件选择对话框 crashdump_viewer:start(File). % 直接加载指定 crashdumpFile 为 string()start/0启动 GUI 并弹出文件对话框对应源码 crashdump_viewer.erlstart/1启动 GUI 并加载指定文件标注since OTP 17.0见 crashdump_viewer.erl。两者内部都委托给cdv_wx:start/1。需要关闭时调用crashdump_viewer:stop/0它会监控后端服务进程并等待其退出。3. Windows 批处理Windows 用户使用与cdv同目录的cdv.bat用法与cdv完全一致cdv.bat [file]。该脚本在构建时由 src/Makefile 中的WIN32_EXECUTABLES目标生成并安装到priv/bin。GUI 主窗口结构当 Crashdump Viewer 成功加载一个 crashdump 后主窗口随之打开从上到下包含四部分标题栏显示当前加载的 crashdump 文件名菜单栏包含File和Help两个菜单File菜单加载新的 crashdump或退出工具Help菜单打开本用户指南以及 ERTS 应用中的 How to interpret the Erlang crash dumps 章节该章节详细讲解原始 crashdump 的每个字段含义也可在 OTP 在线文档中查看信息标签页区域窗口中央区域每个标签页显示某一类信息点击标签标题即可切换状态栏位于窗口底部当当前加载的 dump 被截断truncated时显示警告。标签页的完整集合定义在 cdv_wx.erl 的宏中General、Processes、Ports、ETS Tables、Timers、Schedulers、Funs、Atoms、Nodes、Modules、Memory、Persistent Terms、Internal Tables。列表类标签页与详情窗口对于展示条目列表的标签页例如Processes和Ports可以通过以下方式打开详情窗口双击列表中的某一行右键该行从弹出菜单中选择对应项。详情窗口可以为进程processes、端口ports、节点nodes和模块modules打开。详情窗口中显示的信息可能包含指向其他进程或端口的链接点击链接即可打开对应条目的详情窗口如果目标进程/端口位于远程节点本地没有其信息此时点击链接会弹出一个对话框询问是否打开该远程节点的详情窗口部分标签页如Memory、Internal Tables左侧带有子项菜单点击左侧行右侧信息区即显示对应内容。标签页内容为空的原因如果某个标签页找不到对应信息页面会显示为空。原因有以下几种dump 来自较早的 OTP 版本该版本中并未写入这一项崩溃发生时系统中本来就不存在该项例如某个进程当时尚未创建dump 被截断——此时主窗口状态栏会显示警告。即使部分信息存在如果 dump 来自旧版本 OTP某些字段也可能是空的。需要注意任何字段取值为-1都表示 unknown未知多数情况下意味着 dump 在靠近该字段的位置被截断了。各标签页详解以下字段是原始 crashdump 中不存在、或与原始字段有差异的由 Crashdump Viewer 加工生成其余字段请参考 ERTS 用户指南 How to interpret the Erlang crash dumps 章节可从Help菜单直接打开。General 标签页概览General标签页给出整个 dump 的简要概览以下字段为该页特有字段含义Crashdump created on崩溃发生的时间Memory allocated当前已分配的总字节数等价于erlang:memory(total)的返回值Memory maximum节点生命周期内分配过的最大字节数仅当 Erlang 运行时以 instrumented插桩方式编译运行时才会显示Atoms若 dump 中有原子表大小信息则为原子表内原子总数否则为 dump 中可见的原子数量Processesdump 中可见的进程数ETS tablesdump 中可见的 ETS 表数量Funsdump 中可见的 fun 数量在源码层面这些字段由 cdv_gen_cb.erl 的info_fields/0定义字段名包括slogan、node_name、created、system_vsn、compile_time、taints、mem_totMemory allocated、mem_maxMemory maximum、num_atoms、num_procs、num_ets、num_timers、num_fun、threadCalling Thread。其中mem_tot和mem_max通过{bytes, ...}包装显示时自动格式化为字节单位。Processes 标签页进程Processes标签页列出 crashdump 中所有进程及其简要信息。默认按 pid 排序点击列标题可按其他字段排序。_Memory 列显示自 Erlang/OTP R16B01 起写入 crashdump 的 Memory 字段即该进程使用的内存总量对于更早版本的 dump此列回退显示 Stackheap 字段。单位始终为字节。查看进程详细信息双击该行或右键选择Properties for pid。Ports 标签页端口Ports标签页与Processes标签页类似区别在于列出的是 crashdump 中的所有端口。查看端口详情双击该行或右键选择Properties for port右键菜单中还可以选择Properties for pid其中pid是与该端口相连的进程用于直接跳转到端口控制进程的详情页。ETS Tables 标签页ETS 表ETS Tables标签页显示 dump 中所有 ETS 表信息_Id与原始 crashdump 中的 Table 字段相同_Memory原始 crashdump 中 Words 字段换算为字节后的值对于树形表tree tablesObjects 字段没有值。操作方式双击行或右键选择Properties for Identifier打开表详情右键选择Properties for pid打开该 ETS 表属主进程的详情页。Timers 标签页定时器Timers标签页显示 dump 中所有定时器信息。右键选择Properties for pid可打开定时器属主进程的详情页注意双击Timers标签页中的行没有任何效果源码中该页未绑定双击事件。Schedulers 标签页调度器Schedulers标签页显示 dump 中所有调度器包括普通调度器与 dirty schedulers的信息。双击行或右键选择Properties for Identifier打开对应调度器的详情页。Funs 标签页fun 对象Funs标签页显示 dump 中所有 fun 对象的信息。右键选择Properties for mod打开该 fun 所属模块的详情页与Timers页一样双击Funs页中的行没有效果。Atoms 标签页原子Atoms标签页列出 dump 中所有原子。默认按创建顺序从先到后排序——这与原始 crashdump 正好相反原始文件中的原子从后到前排列。因此如果 dump 在原子列表中间被截断Atoms标签页中只能看到最后创建的原子。Nodes 标签页分布式节点Nodes标签页列出 crashdump 中引用到的所有外部 Erlang 节点。页面为空时表示以下情况之一崩溃节点未启用分布式not distributed节点启用了分布式但没有对其他节点的引用dump 被截断。如果节点是分布式的所有被引用的节点都会显示。_Connection type列表示节点的连接状态状态含义visible存活节点且与崩溃节点保持活跃连接hidden与 visible 相同但该节点以-hidden标志启动not connected已不再与崩溃节点连接但仍存在引用如进程或端口标识符查看节点详情双击行或右键选择Properties for node node右键菜单中还可选择Properties for port打开该节点控制端口的详情窗口节点详情窗口会显示崩溃节点与连接节点之间进程的全部 links 和 monitors_Extra Info字段可能包含调试信息emulator 以 debug 方式编译时写入的特殊信息或错误信息。Modules 标签页模块Modules标签页列出崩溃节点上加载的所有模块及当前代码大小如果存在旧代码old code还会显示旧代码的大小。双击行或右键选择Properties for mod查看模块详情。Memory 标签页内存与分配器Memory标签页展示内存与分配器信息通过左侧菜单选择子项_Memory总体内存信息_Allocator Summary其下所有分配器的汇总值_Allocator每个分配器一项逐项展示_Allocated Areas已分配区域信息。Internal Tables 标签页内部表Internal Tables标签页通过左侧菜单提供三类子项Hash Tables哈希表、Index Tables索引表、Internal ETS Tables内部 ETS 表。源码级实现原理后端解析标签索引机制Crashdump Viewer 的后端 crashdump_viewer.erl 是一个gen_server负责读取并索引 crashdump。其注释明确描述了内部使用的几张 ETS 表cdv_dump_index_table保存从 crashdump 中读到的除binary之外的所有标签tag。在 crashdump 文件中每个标签都以行首的开头表中每个条目记录该标签对应信息在文件中的起始位置cdv_binary_index_table保存所有binary标签。每个二进制对象的十六进制地址先转换为整数值再以Address - Start Position的映射存入查询时从不使用十六进制形式cdv_reg_proc_table保存 pid 与注册名之间的映射用于定时器和监视器monitor信息的展示cdv_heap_file_chars为每个proc_heap和literals标签记录需要从文件中读取的字符数用于解析这些数据时以百分比形式显示进度。解析时以 1000 字节为一块-define(chunk_size, 1000)分块读取文件并定义max_dump_version为[0,5]即当前版本最多支持 0.5 版本的 dump 格式。代码中通过宏定义了全部标签包括proc、port、ets、timer、scheduler、fu、atom、node、memory、allocator、allocated_areas、hash_table、index_table、internal_ets、persistent_terms等标签与信息标签页一一对应。版本兼容性验证测试套件 crashdump_viewer_SUITE.erl 覆盖了关键行为无效文件处理向后端加载内容为unexpected_tag:xyz的文件或空文件时会返回错误file is not an Erlang crash dump\n见该套件中相关用例版本上限检查加载版本高于当前支持上限的 dump 时返回错误This Crashdump Viewer is too old见 crashdump_viewer_SUITE.erl测试中还通过crashdump_viewer:get_dump_versions/0校验当前 dump 版本与 cdv 的最大支持版本一致加载与浏览load_file用例通过crashdump_viewer:start_link()启动后端逐一加载预置的r*_dump.*文件并浏览所有页面见 crashdump_viewer_SUITE.erl。这些测试印证了 dump 太旧/被截断导致信息缺失 以及 版本过新的 dump 无法加载 等文档描述的实际行为。前端渲染按类别的回调模块主窗口 cdv_wx.erl 以wx_object行为实现内部用一个wxNotebook承载全部标签页并为每个标签页维护独立的 panelgen_panel、pro_panel、port_panel、ets_panel、timer_panel、sched_panel、fun_panel、atom_panel、dist_panel、mod_panel、mem_panel、persistent_panel、int_panel。各回调模块通过调用crashdump_viewer的导出函数获取数据例如cdv_gen_cb:get_info/0调用crashdump_viewer:general_info()获取概览字段见 cdv_gen_cb.erlcdv_proc_cb对应processes/0、proc_details/1cdv_ets_cb对应ets_tables/1、internal_ets_tables/0cdv_dist_cb对应dist_info/0、node_info/1后端还提供memory/0、allocator_info/0、allocated_areas/0、hash_tables/0、index_tables/0、schedulers/0、funs/0、atoms/0、timers/1、loaded_modules/0等接口与标签页一一对应完整接口见 crashdump_viewer.erl。值得注意的是后端还有一个expand_binary/1接口配合cdv_bin_cb用于在详情窗口中展开二进制对象内容——这正是点击详情窗口中的二进制引用时能够查看其内部数据的原因。使用建议与局限先看状态栏打开 dump 后如果状态栏出现截断警告那么-1字段、空标签页、缺失进程等异常都属于预期现象不要误判为工具缺陷结合原始 dump 交叉验证Crashdump Viewer 是对原始erl_crash.dump的可视化包装字段含义的权威解释仍在 ERTS 的 How to interpret the Erlang crash dumps 文档中遇到疑点可从Help菜单直接查阅版本限制当前实现的max_dump_version为[0,5]加载更高版本的 dump 会提示 This Crashdump Viewer is too old需要升级 OTP加载旧版本 OTP 产生的 dump 时部分字段如Processes页的 Memory 列、Memory页的 Memory maximum会缺失或回退显示远程节点信息不可用分布式场景下如果进程或端口位于远程节点详情窗口只提供节点级信息无法查看其本地细节依赖 WxWidgetsCrashdump Viewer 是 GUI 工具运行环境需要 Erlang/OTP 以 wx 应用支持即带 Wx 绑定的发行版编译在无图形界面的服务器上建议改用 crash_dump 原始文件解析 或编写脚本处理。相关文档与源码索引用户指南原文crashdump_ug.md命令行参考cdv_cmd.md主模块实现crashdump_viewer.erlGUI 主窗口cdv_wx.erlGeneral 页回调cdv_gen_cb.erl测试套件crashdump_viewer_SUITE.erl原始 dump 格式详解ERTS 文档 crash_dump.md即 How to interpret the Erlang crash dumps【免费下载链接】otpErlang/OTP项目地址: https://gitcode.com/gh_mirrors/ot/otp创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进