内容简介:ByMay 29, 2019LSFMM
A kernel debugger in Python: drgn
By Jake Edge
May 29, 2019
LSFMM
2019 Linux Storage, Filesystem, and Memory-Management Summit (LSFMM)会议上,Omar Sandoval介绍了一款kernel调试器,可以利用 Python 脚本来访问正在运行的kernel里的数据结构。Sandoval是Facebook的一员,他经常需要调试一些kernel问题,总苦恼于当前的 工具 不太趁手。因此他创建了drgn,一个python library形式的kernel debugger(调试器)。
Sandoval首先对drgn(发音同dragon)进行了一个快速演示,登入一台虚拟机,然后用drgn -k命令就连上了当前在运行的Linux kernel,然后用python的交互式 shell 里的几行命令,查看了根文件系统的具体superblock信息,进而循环查看了这个superblock里缓存的inode的信息,包括它们对应的文件路径。然后他演示了一些更有趣的功能,例如列出所有大于1MB的文件的inode。还查看了size比较大的kernel module,库文件,systemd等等。
Sandoval平时经常开发Btrfs和块设备层的代码,不过他也需要调查各种kernel相关的奇怪问题。Facebok有非常多的服务器,有时会有一些“极其罕见的、百万分之一概率的问题”在他们的环境里隔一段时间出现一次。他都会主动帮助调查一下。这个过程中他熟悉了GDB, crash,还有eBPF,不过他很快发现他经常需要对kernel数据结构做各种复杂的分析,所以最终他自己开发了drgn来满足这一需求。
他认为GDB确实有很多优秀功能,包括能把各种类型、变量、公式都很漂亮的打印输出出来。不过它更擅长利用breakpoint(断点)方式的debug,而不适合他在生产环境里debug的需求。GDB支持脚本,但是只是对现有的GDB命令的包装,不够丰富。
Crash也是为内核调试专门开发的工具。它能很好的支持kernel里的链表(linked list,不知道有多少人知道晾衣夹这个梗——译者),各种结构,进程,等等。不过如果要调查其他的内容,就会感到很难下手了,因为它的扩展性不是很强。当Sandoval使用crash的时候,他经常得dump很多数据出来,用其他工具来做进一步的分析处理。
BPF和BCC也都是非常棒的工具,他用这些工具也很频繁。不过通常需要在bug出现的时候采集到具体信息,并且系统得保持正常运行状态,否则无法使用这些工具。很多他调查的bug都是好几个小时之前发生的,server也都因此挂死没法再执行shell命令了,或者他可能只是拿到一份memory dump内存映像文件来debug。这些情况下BPF都没有什么用处了,毕竟BPF主要是用来做tracing方式调试的,不适用于交互式的调试器场景。
Drgn主要目标是能用正式的编程语言来做调试,甚至可以写成真正的程序。Drgn能够很轻松的把需要的信息打印出来,写入文本文件,然后用脚本来处理;也可以直接用Python接口的GDB来调试。他有时候称呼drgn为“debugger as a library”,因为drgn不是像crash或gdb那样,仅仅提供了支持少数几个命令的交互界面。相反的,drgn把所有数据类型、变量等等都包装好了,你可以对他们做任何操作。可以查看这份User Guide来初步了解如何使用(https://drgn.readthedocs.io/en/latest/user_guide.html )。
然后他进行了更进一步的drgn高级功能演示,包括交互式场景,也有脚本方式。首先是演示交互式调试场景,他先让drgn把一个变量作为一个目标object返回回来,这个object还包含更多信息,例如变量类型(也是另一个object),地址,当时的值等。开发者还可以通过链表循环来查看更多信息,他就演示了对struct task_struct这个链表进行遍历,列出了所有从init task到全部子进程的信息。
在现场演示如何使用这个链表遍历功能的时候,他告诉大家,如果经常要重复写这些命令,正常人都会感到乏味无聊。所以drgn还提供了一组helper function帮助函数,能把这部分工作简单化。目前,大多数都是文件系统和块设备层的常用功能,不过很快会加更多网络等kernel其他子系统相关helper function。
接下来,他演示了一次真实事件的debug过程,当时是跟同事一起调查一个虚拟机里的业务服务(production server,特指正在对外提供服务的服务器——译者)。这台服务器是一台存储服务器,主要存放cold data (指不常用的数据),因此磁盘会经常在一段时间没有访问之后被关闭来省电。这样磁盘经常on/off开关的场景下,就触发了一个kernel bug。这里的存储服务是运行在一个container(容器)里的,有时候停止container的操作会卡住无法结束。在他开始查看这个问题的时候,很快他发现container其实在很长时间之后还是停下来了,这里可能是有什么资源泄露了。现场他演示了如何查看block cgroup数据结构,以及Python Set object类型来调查每个block cgroup里的请求队列的数量。他也分析了ID allocator (IDA)关联的radix tree(IDA是用于区分请求队列的),来印证他的分析。最终他看到在一个引用循环(reference cycle)里面,request queue实际上发生了泄露,没有得到回收。
现场他还举了其他的一个例子,是利用drgn来调查Btrfs异常返回ENOSPC的问题。最终查下来是对孤儿文件(orphaned files)保留了额外的metadata空间导致的。一旦确认是这个问题,进而就确认了哪些进程一直在产生孤儿文件,这样在Btrfs的正式fix patch合入之前,可以周期性的重启这个进程来解决。此外,每次他需要调查一个不太熟悉的kernel subsystem的时候,他经常就会用drgn来查看里面的关键数据结构,从而帮助他理解这个子系统。
drgn的核心部分是一个libdrgn C语言库。假如有人不喜欢用python,也希望自己来处理各种异常情况的话,可以直接用 C语言 来调用libdrgn实现调试功能。drgn还有一组可以选择打开与否的后端程序帮助读取各种内存文件,例如正在运行的系统里的/proc/kcore文件,crash dump文件,或者/proc/
优化之后,drgn只要半秒钟就能启动好,而crash需要大概15s的时间启动。drgn启动非常快,所以他越来越喜欢用它,每次要用crash的时候总是有点挠头。
drgn里面还嵌入了一个C语言实现的解析器。这样drgn就能处理不少特殊情况,例如需要做隐性的数据类型转换或者整形数的扩展等等。这部分实现也很麻烦,花了不少时间,不过这样他就能确保相应的转换过的代码运行过程跟在kernel里时一样了。
他也介绍了drgn目前缺失的最大功能是backtrace。现在只能访问全局变量,虽然说大多数情况下也够用了,不过他还是有时候不得不拿出crash工具来获取更多信息,然后帮助drgn来分析当时的情况。backtrace当然也是可以在drgn里支持的,只是他现在还没有完成这部分。后续他很想能用BPF Type Format(BTF)来取代DWARF,因为BTF更加小,更加简单。不过这里有个最大问题是BTF不支持变量,等BTF支持变量之后,他肯定会用BTF。此外他还在准备一组常用的drgn脚本和工具,会提交到git仓库里。
还有一个让他很烦恼的问题,就是是否集成BPF和BCC。有个想法是利用BPF来做存活系统上的debug(live debugging),而drgn用于出错之后的debug(after-the-fact debugging)。这两种工具有些地方是重复的,他还没有想好怎么能统一起来。BPF因为没有循环支持,所以有时候不太好用。而drgn又没法在bug发生的时候及时抓住现场,也不太爽。他有一个“疯狂的想法”,就是在BPF触发breakpoint的位置,调用到user-space的drgn进程,不过这里他还没有想清楚是否完全可行。
译者补充:在LWN的这则新闻下面,有很多评论者提到epython/pykdump,以及crash-python项目,之前经常用crash、并且喜欢python的话,可以试用一下这两个项目。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- 使用 expression 命令调试 UI 问题
- iOS 常用调试方法:LLDB命令
- iOS常用调试方法:LLDB命令
- Wuzz 0.4.0 发布,HTTP 命令行调试工具
- 使用 dotnet 命令行配合 vscode 完成一个完整 .NET 解决方案的编写和调试
- iOS常用调试方法:断点调试
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Is Parallel Programming Hard, And, If So, What Can You Do About
Paul E. McKenney
The purpose of this book is to help you understand how to program shared-memory parallel machines without risking your sanity.1 By describing the algorithms and designs that have worked well in the pa......一起来看看 《Is Parallel Programming Hard, And, If So, What Can You Do About 》 这本书的介绍吧!