<< System语言详解 >> 关于 SystemTap 的书。linux
咱们在分析各类系统异常和故障的时候,一般会用到 pstack(jstack) /pldd/ lsof/ tcpdump/ gdb(jdb)/ netstat/vmstat/ mpstat/truss(strace)/iostat/sar/nmon(top)等系列工具,这些工具从某个方面为咱们提供了诊断信息。但这些工具经常带有各种“反作用”,好比 truss(见于 AIX/Solaris) 或者 strace(见于 Linux) 可以让咱们检测咱们应用的系统调用状况,包括调用参数和返回值,可是却会致使应用程序的性能降低;这对于诊断毫秒级响应的计费生产系统来讲,影响巨大。有没有一个工具,可以兼得上述全部工具的优势,又没有反作用呢?答案是有!对于 Solaris/BSD/OS X 系统来讲,那就是 DTrace 工具(后来,Linux 也终于有了本身相似的工具,stap)。DTrace 的优点是什么呢?能够这么讲,若是你对于 OS 和应用熟悉,利用 DTrace 能够诊断全部问题;没错,是“全部”,“全部”,“全部”,重要的事情说三遍!ios
书籍:DTrace-Dynamic-Tracing-in-Oracle-Solaris-Mac-OS-X-and-FreeBSD.pdfnginx
书籍:Solaris Dynamic Tracing Guide.pdf正则表达式
脚本工具集合:DTraceToolkit-0.99数据库
说到动态追踪就不能不提到DTrace(1)。DTrace 算是现代动态追踪技术的鼻祖了,它于 21 世纪初诞生于 Solaris 操做系统,是由原来的 Sun Microsystems 公司的工程师编写的。可能不少同窗都据说过 Solaris 系统和 Sun 公司的大名。缓存
最初产生的时候,我记得有这样一个故事,当时 Solaris 操做系统的几个工程师花了几天几夜去排查一个看似很是诡异的线上问题。开始他们觉得是很高级的问题,就特别卖力,结果折腾了几天,最后发现实际上是一个很是愚蠢的、某个不起眼的地方的配置问题。自从那件事情以后,这些工程师就痛定思痛,创造了 DTrace 这样一个很是高级的调试工具,来帮助他们在将来的工做当中避免把过多精力花费在愚蠢问题上面。毕竟大部分所谓的“诡异问题”其实都是低级问题,属于那种“调不出来很郁闷,调出来了更郁闷”的类型。安全
应该说 DTrace 是一个很是通用的调试平台,它提供了一种很像 C 语言的脚本语言,叫作 D。基于 DTrace 的调试工具都是使用这种语言编写的。D 语言支持特殊的语法用以指定“探针”,这个“探针”一般有一个位置描述的信息。你能够把它定位在某个内核函数的入口或出口,抑或是某个用户态进程的 函数入口或出口,甚至是任意一条程序语句或机器指令上面。编写 D 语言的调试程序是须要对系统有必定的了解和知识的。这些调试程序是咱们重拾对复杂系统的洞察力的利器。Sun 公司有一位工程师叫作 Brendan Gregg,他是最初的 DTrace 的用户,甚至早于 DTrace 被开源出来。Brendan 编写了不少能够复用的基于 DTrace 的调试工具,一齐放在一个叫作DTrace Toolkit(2)的开源项目中。Dtrace 是最先的动态追踪框架,也是最有名的一个。性能优化
DTrace 的优点是它采起了跟操做系统内核紧密集成的一种方式。D 语言的实现实际上是一个虚拟机(VM),有点像 Java 虚拟机(JVM)。它的一个好处在于 D 语言的运行时是常驻内核的,并且很是小巧,因此每一个调试工具的启动时间和退出时间都很短。可是我以为 DTrace 也是有明显缺点的。其中一个让我很难受的缺点是 D 语言缺少循环结构,这致使许多针对目标进程中的复杂数据结构的分析工具很难编写。虽然 DTrace 官方声称缺乏循环的缘由是为了不过热的循环,但显然 DTrace 是能够在 VM 级别上面有效限制每个循环的执行次数的。另一个较大的缺点是,DTrace 对于用户态代码的追踪支持比较弱,没有自动的加载用户态调试符号的功能,须要本身在 D 语言里面声明用到的用户态 C 语言结构体之类的类型。服务器
DTrace 的影响是很是大的,不少工程师把它移植到其余的操做系统。比方说苹果的 Mac OS X 操做系统上就有 DTrace 的移植。其实近些年发布的每一台苹果笔记本或者台式机上面,都有现成的 dtrace 命令行工具能够调用,你们能够去在苹果机器的命令行终端上尝试一下。这是苹果系统上面的一个 DTrace 的移植。FreeBSD 操做系统也有这样一个 DTrace 的移植。只不过它并非默认启用的。你须要经过命令去加载 FreeBSD 的 DTrace 内核模块。Oracle 也有在它本身的 Oracle Linux 操做系统发行版当中开始针对 Linux 内核进行 DTrace 移植。不过 Oracle 的移植工做好像一直没有多少转机,毕竟 Linux 内核并非 Oracle 控制的,而 DTrace 是须要和操做系统内核紧密集成的。出于相似的缘由,民间一些勇敢的工程师尝试的 DTrace 的 Linux 移植也一直距离生产级别的要求很远。网络
相比 Solaris 上面原生的 DTrace,这些 DTrace 移植都或多或少的缺少某些高级特性,因此从能力上来讲,还不及最本初的 DTrace。
DTrace 对 Linux 操做系统的另外一个影响反映在SystemTap(3)这个开源项目。这是由 Red Hat 公司的工程师建立的较为独立的动态追踪框架。SystemTap 提供了本身的一种小语言(4),和 D 语言并不相同。显然,Red Hat 本身服务于很是多的企业级用户,他们的工程师天天须要处理的各类线上的“诡异问题”天然也是极多的。这种技术的产生必然是现实需求激发的。我以为 SystemTap 是目前 Linux 世界功能最强大,同时也是最实用的动态追踪框架。我在本身的工做当中已经成功使用多年。SystemTap 的做者 Frank Ch. Eigler 和 Josh Stone 等人,都是很是热情、同时很是聪明的工程师。我在 IRC 或者邮件列表里的提问,他们通常都会很是快且很是详尽地进行解答。值得一提的是,我也曾给 SystemTap 贡献过一个较为重要的新特性,使其能在任意的探针上下文中访问用户态的全局变量的取值。我当时合并到 SystemTap 主线的这个C++ 补丁(5)的规模达到了约一千行,多亏了 SystemTap 做者们的热心帮助。这个新特性在我基于 SystemTap 实现的动态脚本语言(好比 Perl 和 Lua)的火焰图(6)工具中扮演了关键角色。
SystemTap 的优势是它有很是成熟的用户态调试符号的自动加载,同时也有循环这样的语言结构能够去编写比较复杂的探针处理程序,能够支持不少很复杂的分析处理。因为 SystemTap 早些年在实现上的不成熟,致使互联网上充斥着不少针对它的已通过时了的诟病和批评。最近几年 SystemTap 已然有了长足的进步。
固然,SystemTap 也是有缺点的。首先,它并非 Linux 内核的一部分,就是说它并无与内核紧密集成,因此它须要一直不停地追赶主线内核的变化。另外一个缺点是,它一般是把它的“小语言”脚本(有点像 D 语言哦)动态编译成一个 Linux 内核模块的 C 源码,所以常常须要在线部署 C 编译器工具链和 Linux 内核的头文件,同时须要动态地加载这些编译出来的内核模块,以运行咱们的调试逻辑。在咱们的调试工具运行完毕以后,又存在动态卸载 Linux 内核模块的问题。出于这些缘由,SystemTap 脚本的启动相比 DTrace 要慢得多,和 JVM 的启动时间倒有几分相似。虽然存在这些缺点,但总的来讲,SystemTap 仍是一个很是成熟的动态追踪框架。
不管是 DTrace 仍是 SystemTap,其实都不支持编写完整的调试工具,由于它们都缺乏方便的命令行交互的原语。因此咱们才看到现实世界中许多基于它们的工具,其实最外面都有一个 Perl、Python 或者 Shell 脚本编写的包裹。为了便于使用一种干净的语言编写完整的调试工具,我曾经给 SystemTap 语言进行了扩展,实现了一个更高层的“宏语言”,叫作stap++(7)。我本身用 Perl 实现的 stap++ 解释器能够直接解释执行 stap++ 源码,并在内部调用 SystemTap 命令行工具。有兴趣的朋友能够查看我开源在 GitHub 上面的 stapxx 这个代码仓库。这个仓库里面也包含了不少直接使用个人 stap++ 宏语言实现的完整的调试工具。
DTrace 有今天这么大的影响离不开著名的 DTrace 布道士Brendan Gregg(8)老师。前面咱们也提到了他的名字。他最初是在 Sun Microsystems 公司,工做在 Solaris 的文件系统优化团队,是最先的 DTrace 用户。他写过好几本有关 DTrace 和性能优化方面的书,也写过不少动态追踪方面的博客文章。
2011 年我离开淘宝之后,曾经在福州过了一年所谓的“田园生活”。在田园生活的最后几个月当中,我经过 Brendan 的公开博客(9)较为系统地学习了 DTrace 和动态追踪技术。其实最先据说 DTrace 是由于一位微博好友的评论,他只提到了 DTrace 这个名字。因而我便想了解一下这到底是什么东西。谁知,不了解不知道,一了解吓一跳。这居然是一个全新的世界,完全改变了我对整个计算世界的见解。因而我就花了很是多的时间,一篇一篇地仔细精读 Brendan 的我的博客。后来终于有一天,我有了一种大彻大悟的感受,终于能够融会贯通,掌握到了动态追踪技术的精妙。
2012 年我结束了在福州的“田园生活”,来到美国加入目前这家 CDN 公司。而后我就当即开始着手把 SystemTap 以及我已领悟到的动态追踪的一整套方法,应用到这家 CDN 公司的全球网络当中去,用于解决那些很是诡异很是奇怪的线上问题。我在这家公司观察到其实不少工程师在排查线上问题的时候,常常会本身在软件系统里面埋点。这主要是在业务代码里,乃至于像 Nginx 这样的系统软件的代码基(code base)里,本身去作修改,添加一些计数器,或者去埋下一些记录日志的点。经过这种方式,大量的日志会在线上被实时地采集起来,进入专门的数据库,而后再进行离线分析。显然这种作法的成本是巨大的,不只涉及业务系统自己的修改和维护成本的陡然提升,并且全量采集和存储大量的埋点信息的在线开销,也是很是可观的。并且常常出现的状况是,张三今天在业务代码里面埋了一个采集点,李四明天又埋下另外一个类似的点,过后可能这些点又都被遗忘在了代码基里面,而没有人再去理会。最后这种点会愈来愈多,把代码基搞得愈来愈凌乱。这种侵入式的修改,会致使相应的软件,不管是系统软件仍是业务代码,变得愈来愈难以维护。
埋点的方式主要存在两大问题,一个是“太多”的问题,一个是“太少”的问题。“太多”是指咱们每每会采集一些根本不须要的信息,只是一时贪多贪全,从而形成没必要要的采集和存储开销。不少时候咱们经过采样就能进行分析的问题,可能会习惯性的进行全网全量的采集,这种代价累积起来显然是很是昂贵的。那“太少”的问题是指,咱们每每很难在一开始就规划好所需的全部信息采集点,毕竟没有人是先知,能够预知将来须要排查的问题。因此当咱们遇到新问题时,现有的采集点搜集到的信息几乎老是不够用的。这就致使频繁地修改软件系统,频繁地进行上线操做,大大增长了开发工程师和运维工程师的工做量,同时增长了线上发生更大故障的风险。
另一种暴力调试的作法也是咱们某些运维工程师常常采用的,即把机器拉下线,而后设置一系列临时的防火墙规则,以屏蔽用户流量或者本身的监控流量,而后在生产机上各类折腾。这是很繁琐影响很大的过程。首先它会让机器不能再继续服务,下降了整个在线系统的总的吞吐能力。同时有些只有真实流量才能复现的问题,此时再也没法复现了。能够想象这些粗暴的作法有多么让人头疼。
实际上运用 SystemTap 动态追踪技术能够很好地解决这样的问题,有“润物细无声”之妙。首先咱们不须要去修改咱们的软件栈(software stack)自己,无论是系统软件仍是业务软件。我常常会编写一些有针对性的工具,而后在一些关键的系统「穴位」上面放置一些通过仔细安排的探针。这些探针会采集各自的信息,同时调试工具会把这些信息汇总起来输出到终端。用这种方式我能够在某一台机器或某几台机器上面,经过采样的方式,很快地获得我想要的关键信息,从而快速地回答一些很是基本的问题,给后续的调试工做指明方向。
正如我前面提到的,与其在生产系统里面人工去埋点去记日志,再搜集日志入库,还不如把整个生产系统自己当作是一个能够直接查询的“数据库”,咱们直接从这个“数据库”里安全快捷地获得咱们想要的信息,并且毫不留痕迹,毫不去采集咱们不须要的信息。利用这种思想,我编写了不少调试工具,绝大部分已经开源在了 GitHub 上面,不少是针对像 Nginx、LuaJIT 和操做系统内核这样的系统软件,也有一些是针对更高层面的像 OpenResty 这样的 Web 框架。有兴趣的朋友能够查看 GitHub 上面的nginx-systemtap-toolkit(10)、perl-systemtap-toolkit(11)和stappxx(12)这几个代码仓库。
个人 SystemTap 工具云
利用这些工具,我成功地定位了数不清的线上问题,有些问题甚至是我意外发现的。下面就随便举几个例子吧。
第一个例子是,我使用基于 SystemTap 的火焰图工具分析咱们线上的 Nginx 进程,结果发现有至关一部分 CPU 时间花费在了一条很是奇怪的代码路径上面。这实际上是我一位同事在好久以前调试一个老问题时遗留下来的临时的调试代码,有点儿像咱们前面提到的“埋点代码”。结果它就这样被遗忘在了线上,遗忘在了公司代码仓库里,虽然当时那个问题其实早已解决。因为这个代价高昂的“埋点代码”一直没有去除,因此一直都产生着较大的性能损耗,而一直都没有人注意到。因此可谓是我意外的发现。当时我就是经过采样的方式,让工具自动绘制出一张火焰图。我一看这张图就能够发现问题并能采起措施。这是很是很是有效的方式。
第二个例子是,不多量的请求存在延时较长的问题,即所谓的“长尾请求”。这些请求数目很低,但可能达到「秒级」这样的延时。当时有同事乱猜说是个人 OpenResty 有 bug,我不服气,因而当即编写了一个 SystemTap 工具去在线进行采样,对那些超过一秒总延时的请求进行分析。该工具会直接测试这些问题请求内部的时间分布,包括请求处理过程当中各个典型 I/O 操做的延时以及纯 CPU 计算延时。结果很快定位到是 OpenResty 在访问 Go 编写的 DNS 服务器时,出现延时缓慢。而后我再让个人工具输出这些长尾 DNS 查询的具体内容,发现都是涉及 CNAME 展开。显然,这与OpenResty 无关了,而进一步的排查和优化也有了明确的方向。
第三个例子是,咱们曾注意到某一个机房的机器存在比例明显高于其余机房的网络超时的问题,但也只有 1% 的比例。一开始咱们很天然的去怀疑网络协议栈方面的细节。但后来我经过一系列专门的 SystemTap 工具直接分析那些超时请求的内部细节,便定位到了是硬盘 配置方面的问题。从网络到硬盘,这种调试是很是有趣的。第一手的数据让咱们快速走上正确的轨道。
还有一个例子是,咱们曾经经过火焰图在 Nginx 进程里观察到文件的打开和关闭操做占用了较多的 CPU 时间,因而咱们很天然地启用了 Nginx 自身的文件句柄缓存配置,可是优化效果并不明显。因而再作出一张新的火焰图,便发现由于这回轮到 Nginx 的文件句柄缓存的元数据所使用的“自旋锁”占用不少 CPU 时间了。这是由于咱们虽然启用了缓存,但把缓存的大小设置得过大,因此致使元数据的自旋锁的开销抵消掉了缓存带来的好处。这一切都能在火焰图上面一目了然地看出来。假设咱们没有火焰图,而只是盲目地试验,极可能会得出 Nginx 的文件句柄缓存没用的错误结论,而不会去想到去调整缓存的参数。
最后一个例子是,咱们在某一次上线操做以后,在线上最新的火焰图中观察到正则表达式的编译操做占用了不少 CPU 时间,但其实咱们已经在线上启用了正则编译结果的缓存。很显然,咱们业务系统中用到的正则表达式的数量,已然超出了咱们最初设置的缓存大小,因而很天然地想到把线上的正则缓存调的更大一些。而后,咱们在线上的火焰图中便再看不到正则编译操做了。
经过这些例子咱们其实能够看到,不一样的数据中心,不一样的机器,乃至同一台机器的不一样时段,都会产生本身特有的一些新问题。咱们须要的是直接对问题自己进行分析,进行采样,而不是胡乱去猜想去试错。有了强大的工具,排错实际上是一个事半功倍的事情。
前面咱们已经屡次提到了火焰图(Flame Graph)这种东西(systemtap 能够制做火焰图, perf 命令也能够制做火焰图),那么火焰图是什么呢?它实际上是一个很是了不得的可视化方法,是由前面已经反复提到的 Brendan Gregg 同窗发明的。
火焰图就像是给一个软件系统拍的 X 光照片,能够很天然地把时间和空间两个维度上的信息融合在一张图上,以很是直观的形式展示出来,从而反映系统在性能方面的不少定量的统计规律。
Nginx 的 C 级别 on-CPU 火焰图示例
比方说,最经典的火焰图是统计某一个软件的全部代码路径在 CPU 上面的时间分布。经过这张分布图咱们就能够直观地看出哪些代码路径花费的 CPU 时间较多,而哪些则是可有可无的。进一步地,咱们能够在不一样的软件层面上生成火焰图,好比说能够在系统软件的 C/C++ 语言层面上画出一张图,而后再在更高的——好比说——动态脚本语言的层面,例如 Lua 和 Perl 代码的层面,画出火焰图。不一样层面的火焰图经常会提供不一样的视角,从而反映出不一样层面上的代码热点。
由于我本身维护着 OpenResty 这样的开源软件的社区,咱们有本身的邮件列表,我常常会鼓励报告问题的用户主动提供本身绘制的火焰图,这样咱们就能够惬意地看图说话(13),帮助用户快速地进行性能问题的定位,而不至于反复地试错,和用户一块儿去胡乱猜想,从而节约彼此大量的时间,皆大欢喜。
这里值得注意的是,即便是遇到咱们并不了解的陌生程序,经过看火焰图,也能够大体推出性能问题的所在,即便从未阅读过它的一行源码。这是一件很是了不得的事情。由于大部分程序实际上是编写良好的,也就是说它每每在软件构造的时候就使用了抽象层次,好比经过函数。这些函数的名称一般会包含语义上的信息,并在火焰图上面直接显示出来。经过这些函数名,咱们能够大体推测出对应的函数,乃至对应的某一条代码路径,大体是作什么事情的,从而推断出这个程序所存在的性能问题。因此,又回到那句老话,程序代码中的命名很是重要,不只有助于阅读源码,也有助于调试问题。而反过来,火焰图也为咱们提供了一条学习陌生的软件系统的捷径。毕竟重要的代码路径,几乎老是花费时间较多的那些,因此值得咱们重点研究;不然的话,这个软件的构造方式必然存在很大的问题。
火焰图其实能够拓展到其余维度,好比刚才咱们讲的火焰图是看程序运行在 CPU 上的时间在全部代码路径上的分布,这是 on-CPU 时间这个维度。相似地,某一个进程不运行在任何 CPU 上的时间其实也是很是有趣的,咱们称之为 off-CPU 时间。off-CPU 时间通常是这个进程由于某种缘由处于休眠状态,好比说在等待某一个系统级别的锁,或者被一个很是繁忙的进程调度器(scheduler)强行剥夺 CPU 时间片。这些状况都会致使这个进程没法运行在 CPU 上,可是仍然花费不少的挂钟时间。经过这个维度的火焰图咱们能够获得另外一幅很不同的图景。经过这个维度上的信息,咱们能够分析系统锁方面的开销(好比sem_wait
这样的系统调用),某些阻塞的 I/O 操做(例如open
、read
之类),还能够分析进程或线程之间争用 CPU 的问题。经过 off-CPU 火焰图,都一目了然。
应该说 off-CPU 火焰图也算是我本身的一个大胆尝试。记得最初我在加州和内华达州之间的一个叫作 Tahoe 的湖泊边,阅读 Brendan 关于 off-CPU 时间的一篇博客文章(14)。我固然就想到,或许能够把 off-CPU 时间代替 on-CPU 时间应用到火焰图这种展示方式上去。因而回来后我就在公司的生产系统中作了这样一个尝试,使用 SystemTap 绘制出了 Nginx 进程的 off-CPU 火焰图。我在推特上公布了这个成功尝试以后,Brendan 还专门联系到我,说他本身以前也尝试过这种方式,但效果并不理想。我估计这是由于他当时将之应用于多线程的程序,好比 MySQL,而多线程的程序由于线程同步方面的缘由,off-CPU 图上会有不少噪音,容易掩盖真正有趣的那些部分。而我应用 off-CPU 火焰图的场景是像 Nginx 这样的单线程程序,因此 off-CPU 火焰图里每每会当即指示出那些阻塞 Nginx 事件循环的系统调用,抑或是sem_wait
之类的锁操做,又或者是抢占式的进程调度器的强行介入,因而能够很是好地帮助分析一大类的性能问题。在这样的 off-CPU 火焰图中,惟一的“噪音”其实就是 Nginx 事件循环自己的epoll_wait
这样的系统调用,很容易识别并忽略掉。
因为 Linux 的开放性的缘故,在 Linux 下有好几种内存转储机制。下面将对它们分别作简要的介绍。
LKCD(Linux Kernel Crash Dump) 是 Linux 下第一个内核崩溃内存转储项目,它最初由 SGI 的工程师开发和维护。它提供了一种可靠的方法来发现、保存和检查系统的崩溃。LKCD 做为 Linux 内核的一个补丁,它一直以来都没有被接收进入内核的主线。目前该项目已经彻底中止开发。
Diskdump 是另一个内核崩溃内存转储的内核补丁,它由塔高 (Takao Indoh) 在 2004 年开发出来。与 LKCD 相比,Diskdump 更加简单。当系统崩溃时,Diskdump 对系统有彻底的控制。为避免混乱,它首先关闭全部的中断;在 SMP 系统上,它还会把其余的 CPU 停掉。而后它校验它本身的代码,若是代码与初始化时不同。它会认为它已经被破坏,并拒绝继续运行。而后 Diskdump 选择一个位置来存放内存转储。Diskdump 做为一个内核的补丁,也没有被接收进入内核的主线。在众多的发行版中,它也只获得了 RedHat 的支持。
RedHat 在它的 Linux 高级服务器 2.1 的版本中,提供了它本身的第一个内核崩溃内存转储机制:Netdump。 与 LKCD 和 Diskdump 将内存转储保存在本地磁盘不一样,当系统崩溃时,Netdump 将内存转储文件经过网络保存到远程机器中。RedHat 认为采用网络方式比采用磁盘保的方式要简单,由于当系统崩溃时,能够在没有中断的状况下使用网卡的论询模式来进行网络数据传送。同时,网络方式对内存转储文件提供了更好的管理支持。与 Diskdump 同样,Netdump 没有被接收进入内核的主线,目前也只有 RedHat 的发行版对 Netdump 提供支持。
Kdump 是一种基于 kexec 的内存转储工具,目前它已经被内核主线接收,成为了内核的一部分,它也由此得到了绝大多数 Linux 发行版的支持。与传统的内存转储机制不一样不一样,基于 Kdump 的系统工做的时候须要两个内核,一个称为系统内核,即系统正常工做时运行的内核;另一个称为捕获内核,即正常内核崩溃时,用来进行内存转储的内核。 在本文稍后的内容中,将会介绍如何设置 kump。
MKdump(mini kernel dump) 是 NTT 数据和 VA Linux 开发另外一个内核内存转储工具,它与 Kdump 相似,都是基于 kexec,都须要使用两个内核来工做。其中一个是系统内核;另一个是 mini 内核,用来进行内存转储。与 Kdump 相比,它有如下特色:
与具备众多的内存转储机制同样,Linux 下也有众多的内存转储分析工具,下面将会逐一作简单介绍。
Lcrash 是随 LKCD 一块儿发布的一个内内存储分析工具。随着 LKCD 开发的中止,lcrash 的开发也同时中止了。目前它的代码已经被合并进入 Crash 工具中。
Alicia (Advanced Linux Crash-dump Interactive Analyzer,高级 Linux 崩溃内存转储交互分析器 ) 是一个创建在 lcrash 和 Crash 工具之上的一个内存转储分析工具。它使用 Perl 语言封装了 Lcrash 和 Crash 的底层命令,向用户提供了一个更加友好的交互方式和界面。Alicia 目前的开发也已经停滞。
Crash 是由 Dave Anderson 开发和维护的一个内存转储分析工具,目前它的最新版本是 5.0.0。 在没有统一标准的内存转储文件的格式的状况下,Crash 工具支持众多的内存转储文件格式,包括: