news 2026/9/24 16:01:51

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

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Erlang/OTP Crashdump Viewer(cdv)使用指南:从崩溃转储到问题定位的可视化分析

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

【免费下载链接】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 Viewer

Crashdump 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_wxcdv_virtual_list_wx等负责渲染,以及一组按数据类别划分的回调模块cdv_gen_cbcdv_proc_cbcdv_port_cbcdv_ets_cbcdv_timer_cbcdv_sched_cbcdv_fun_cbcdv_atom_cbcdv_dist_cbcdv_mod_cbcdv_mem_cbcdv_int_tab_cbcdv_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/0script_start/1do_script_start/1script_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). % 直接加载指定 crashdump,File 为 string()
  • start/0:启动 GUI 并弹出文件对话框,对应源码 crashdump_viewer.erl;
  • start/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 文件名;
  • 菜单栏:包含FileHelp两个菜单;
    • File菜单:加载新的 crashdump,或退出工具;
    • Help菜单:打开本用户指南,以及 ERTS 应用中的 "How to interpret the Erlang crash dumps" 章节(该章节详细讲解原始 crashdump 的每个字段含义,也可在 OTP 在线文档中查看);
  • 信息标签页区域:窗口中央区域,每个标签页显示某一类信息;点击标签标题即可切换;
  • 状态栏:位于窗口底部,当当前加载的 dump 被截断(truncated)时显示警告。

标签页的完整集合定义在 cdv_wx.erl 的宏中:GeneralProcessesPortsETS TablesTimersSchedulersFunsAtomsNodesModulesMemoryPersistent TermsInternal Tables

列表类标签页与详情窗口

对于展示条目列表的标签页(例如ProcessesPorts),可以通过以下方式打开详情窗口

  • 双击列表中的某一行;
  • 右键该行,从弹出菜单中选择对应项。

详情窗口可以为进程(processes)、端口(ports)、节点(nodes)和模块(modules)打开。详情窗口中显示的信息可能包含指向其他进程或端口的链接,点击链接即可打开对应条目的详情窗口:

  • 如果目标进程/端口位于远程节点,本地没有其信息,此时点击链接会弹出一个对话框,询问是否打开该远程节点的详情窗口;
  • 部分标签页(如MemoryInternal 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定义,字段名包括slogannode_namecreatedsystem_vsncompile_timetaintsmem_tot(Memory allocated)、mem_max(Memory maximum)、num_atomsnum_procsnum_etsnum_timersnum_funthread(Calling Thread)。其中mem_totmem_max通过{bytes, ...}包装,显示时自动格式化为字节单位。

Processes 标签页(进程)

Processes标签页列出 crashdump 中所有进程及其简要信息。默认按 pid 排序,点击列标题可按其他字段排序。

  • _Memory 列:显示自 Erlang/OTP R16B01 起写入 crashdump 的 'Memory' 字段,即该进程使用的内存总量;对于更早版本的 dump,此列回退显示 'Stack+heap' 字段。单位始终为字节。
  • 查看进程详细信息:双击该行,或右键选择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 tables),'Objects' 字段没有值。

操作方式:双击行或右键选择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_heapliterals标签记录需要从文件中读取的字符数,用于解析这些数据时以百分比形式显示进度。

解析时以 1000 字节为一块(-define(chunk_size, 1000))分块读取文件,并定义max_dump_version[0,5],即当前版本最多支持 0.5 版本的 dump 格式。代码中通过宏定义了全部标签,包括procportetstimerschedulerfuatomnodememoryallocatorallocated_areashash_tableindex_tableinternal_etspersistent_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承载全部标签页,并为每个标签页维护独立的 panel(gen_panelpro_panelport_panelets_paneltimer_panelsched_panelfun_panelatom_paneldist_panelmod_panelmem_panelpersistent_panelint_panel)。各回调模块通过调用crashdump_viewer的导出函数获取数据,例如:

  • cdv_gen_cb:get_info/0调用crashdump_viewer:general_info()获取概览字段(见 cdv_gen_cb.erl);
  • cdv_proc_cb对应processes/0proc_details/1
  • cdv_ets_cb对应ets_tables/1internal_ets_tables/0
  • cdv_dist_cb对应dist_info/0node_info/1
  • 后端还提供memory/0allocator_info/0allocated_areas/0hash_tables/0index_tables/0schedulers/0funs/0atoms/0timers/1loaded_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)会缺失或回退显示;
  • 远程节点信息不可用:分布式场景下,如果进程或端口位于远程节点,详情窗口只提供节点级信息,无法查看其本地细节;
  • 依赖 WxWidgets:Crashdump Viewer 是 GUI 工具,运行环境需要 Erlang/OTP 以 wx 应用支持(即带 Wx 绑定的发行版)编译,在无图形界面的服务器上建议改用 crash_dump 原始文件解析 或编写脚本处理。

相关文档与源码索引

  • 用户指南原文:crashdump_ug.md
  • 命令行参考:cdv_cmd.md
  • 主模块实现:crashdump_viewer.erl
  • GUI 主窗口:cdv_wx.erl
  • General 页回调: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),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/24 16:00:42

真空喷涂机品牌推荐:从工艺流程到设备选型多维度完整分析

在水产饲料和宠物食品加工中&#xff0c;油脂、诱食剂及部分热敏性营养组分通常需要在膨化和烘干后添加。真空喷涂机在不同真空度情况下&#xff0c;使脂肪或脂溶性的维生素等液体原料渗透到颗粒内部&#xff0c;提高液体添加比例&#xff0c;满足动物能量要求。布勒围绕水产饲…

作者头像 李华
网站建设 2026/9/24 15:59:43

如何快速提高物理实验中的误差控制能力

快速提升物理实验误差控制能力&#xff0c;核心是分层针对性训练标准化流程固化&#xff0c;不用高端实验室&#xff0c;1-2个月就能把普通物理实验的结果相对误差稳定控制在1%以内&#xff0c;完全适配你家孩子轻量低负担的学习节奏&#xff1a; &#x1f4cf; 第一阶段&#…

作者头像 李华
网站建设 2026/9/24 15:59:40

DRF 3.x APP Model Serializer 应用模型序列化使用示例和配置方法

在现代Web API开发中,数据序列化是后端与前端、以及不同服务之间传递和处理数据的关键环节。Django REST Framework(DRF)提供了一系列强大而灵活的序列化器,帮助开发者将复杂的模型数据转换为适合API的输出格式。 本文详细介绍了DRF中序列化器的常用字段、特殊字段、高级字…

作者头像 李华
网站建设 2026/9/24 15:58:28

自研充电桩系统充电桩小程序:稳定兼容+全功能闭环

博主介绍&#xff1a; 所有项目都配有从入门到精通的安装教程&#xff0c;可二开&#xff0c;提供核心代码讲解&#xff0c;项目指导。 项目配有对应开发文档、解析等 项目都录了发布和功能操作演示视频&#xff1b;项目的界面和功能都可以定制&#xff0c;包安装运行&#xff…

作者头像 李华
网站建设 2026/9/24 15:57:22

从2小时会议录像到关键片段:FunClip零代码AI视频剪辑实战笔记

从2小时会议录像到关键片段&#xff1a;FunClip零代码AI视频剪辑实战笔记 【免费下载链接】FunClip FunASR-powered video transcription, subtitle generation, and LLM-assisted clipping tool with a local Gradio UI. 项目地址: https://gitcode.com/GitHub_Trending/fu/…

作者头像 李华