我们总是时不时的提起调试。现在我们就好好看看这玩意儿。宽泛点说,调试就是在系统中发现和修复问题的行为,包括硬件和软件。性能问题也认为是bug,所以调试也包括性能调优,也就是寻求通过去除处理过程中的瓶颈来改善性能。接下来,我们会提到调试的过程、内核错误以及性能问题。暂时不涉及硬件调试。
错误分析如果一个进程发生了错误,大多数的操作系统会把错误信息写进日志文件从来警告管理员或用户有问题发生了。操作系统也会用core dump(核心转储),是进程地址空间的内容以及有关进程状态的其他信息写出的一个磁盘文件,用来之后分析。运行的程序和core dump可以通过调试器探测到,这可以让程序员检查代码并且查看失败时进程地址空间到底发生了什么。
调试用户级别的进程代码是一个挑战。因为内核的大小和复杂度,操作系统的内核调试更是复杂,它既控制着硬件,有缺少用户级别的调试工具。当crash发生时,错误信息会被保存到日志文件中,内存状态信息会被保存到crash dump。
操作系统的调试和进程调试,因为这两个任务天生的不同而通常使用不同的工具和技术。考虑到文件系统代码中的内核故障会导致内核在重启之前尝试将其状态保存到下文件系统上的文件中的风险,一种常见的技术是将内核的内存状态保存到为此保留的一部分磁盘中,该部分不包含文件系统。如果内存检测到不可回复的错误,则会将内存的全部内容,或至少是系统内存中内核拥有的部分,写入该磁盘区域。当系统重启时,将运行一个进程从该区域收集数据并将其写入文件系统中的crash dump文件中以进行分析。显然,这样的策略对于调试普通的用户进程是没有必要的。
性能监测和调优我们之前性能调优就是提过通过去除处理过程中瓶颈来寻求改善性能。为了识别瓶颈,我们必须能够监测系统性能呢个。因此,操作系统必须有一些方式用来计算和展示系统的行为。根据是按每个进程或整个系统的观测角度的不同,每个工具都有自己的特征。为了达成这些观测,工具会使用这两个方法中的一个 --- counters计数或追踪tracing。下面,我们会探究一下这俩玩意儿。
计数器操作系统通过一系列的计数器保持对系统行为的追踪,比如系统调用的次数或是对网络设备或磁盘的操作次数。下面是Liunx用作计数器的工具:
进城级ps - 报告对单个或选中进程的信息top - 报告当前进程们的实时统计信息系统级vmstat - 报告内存使用的统计netstat - 报告网络接口门的统计信息iostat - 包括对磁盘的I/O使用情况在Linux中大多数基于计数的工具都是从/proc文件系统里读取统计信息的。/proc是一个假的文件系统,它只存在于内核的内存中,并且主要被用来查寻各个进程和内核的统计信息。/ proc文件系统组织为目录层次结构,每个进程(分配给每个进程的唯一整数值)显示为/ proc下的子目录。例如,目录条目/ proc / 2155将包含ID为2155的进程的每个进程统计信息。/proc这也有各种条目,用于各种内核统计信息,如下图:
Unbuntu中也提供了一个系统监测应用,一个包含进程进程,系统资源,和文件系统信息的工具。截图如下:
Ubuntu中的系统监测工具
追踪尽管基于计数的工具只是简单的查询内核维护的某些统计信息中的当前值,但追踪工具则收集一些特殊时间的数据,诸如系统调用中包含的每一步。
下面是Linux中追踪事件工具的示例:
进程级strace - 追踪单个进程的系统调用gdb - 一个源代码级的调试器系统级perf - Linux性能收集工具tcpdump - 采集网络包柯林汉定律 (Kernighan's Law)
调试在一开始就比编写程序困难一倍。因此,按照定义,如果你的代码写得非常巧妙,那么你就没有足够的能力来调试它。
使操作系统在运行时更易于理解,调试和调优是研究和实践的活跃领域。新一代支持内核的性能分析工具在实现此目标的方式上有了重大改进。接下来,我们讨论BCC,一个动态Linux内核追踪工具包。
BCC如果没有能够理解两组代码并能够检测它们之间的交互作用的工具集,几乎不可能调试用户级代码与内核代码之间的交互。为了使该工具集真正有用,它必须能够调试系统的任何区域,包括未考虑调试的部分,并且在不影响系统可靠性的情况下进行调试。该工具集还必须对性能产生最小的影响-理想情况下,它在不使用时不受影响,而在使用中的影响是不成比例。 BCC工具箱满足了这些要求,并提供了动态,安全,低影响的调试环境。
BBC(BPF Compiler Collection)是个丰富的工具包,用于提供对Linux系统的追踪。BCC是e BPF(extended Berkeley Packet Filter,扩展的Berkeley数据包过滤器)工具的前端接口。 BPF技术是在1990年代初开发的,用于过滤计算机网络中的流量。 “extened扩展的” BPF(e BPF)为BPF添加了各种功能。 BPF程序是用C的子集编写的,并被编译成e BPF指令,这些指令可以动态地插入正在运行的Linux系统中。 e BPF指令可用于捕获特定事件(例如正在调用的某个系统调用)或监视系统性能(例如执行磁盘I / O所需的时间)。为了确保BPF指令的行为良好,在插入运行Linux内核之前,它们会通过verifier验证者传入。验证者会进行检查以确保说明不会影响系统性能或安全性。
尽管e BPF为Linux内核中的跟踪提供了丰富的功能集,但是从传统上来说,使用其C接口开发程序非常困难。开发BCC的目的是通过在Python中提供一个前端接口来简化使用e BPF编写工具的过程。 BCC工具是用Python编写的,它嵌入了与e BPF工具接口的C代码,后者又与内核接口。 BCC工具还将C程序编译为e BPF指令,并使用探测或将其跟踪点插入内核中,这是两种允许在Linux内核中跟踪事件的技术。
编写自定义BCC工具的细节不在讨论范围之内,但是BCC软件包提供了许多现有工具,用于监视正在运行的Linux内核中多个活动区域。
ubuntu下的安装命令如下:
sudo apt-get install bpfcc-tools linux-headers-$(uname -r)其他系统可参考https://github.com/iovisor/bcc/blob/master/INSTALL.md
使BCC特别强大的是,它的工具可以在运行关键应用程序的实时生产系统上使用,而不会对系统造成损害。这对于必须监视系统性能以识别可能的瓶颈或安全漏洞的系统管理员特别有用。下图说明了BCC和e BPF当前提供的各种工具,以及它们跟踪Linux操作系统的几乎任何区域的能力。 BCC是一种快速变化的技术,不断地被添加新功能。