《Effective Debugging:软件和系统调试的66个有效方法》——第16条:使用专门的监测及测试设备-阿里云开发者社区

开发者社区> 华章出版社> 正文
登录阅读全文

《Effective Debugging:软件和系统调试的66个有效方法》——第16条:使用专门的监测及测试设备

简介:

本节书摘来自华章计算机《Effective Debugging:软件和系统调试的66个有效方法》一书中的第2章,第16节,作者[希]迪欧米迪斯·斯宾奈里斯(Diomidis Spinellis),爱飞翔 译,更多章节内容可以访问云栖社区“华章计算机”公众号查看。

第16条:使用专门的监测及测试设备

调试嵌入式系统及系统软件的时候,我们可能要对从硬件到应用程序的整个计算栈进行分析。调试工作一旦深入硬件层面,我们就需要关注电流的微小变化以及磁矩的对齐情况等细节。在大多数情况下,可以通过强大的IDE以及一些追踪软件与日志记录软件来探查这些问题,然而有的时候,就连这些工具也帮不上忙。这通常发生在软件与硬件有所接触的场合,也就是说,虽然你认为你所写的软件能够像预期的那样运作,但是硬件却有着它自己的处理方式。例如,你把正确的数据写入磁盘,再将其读取出来,却发现这些数据似乎已经损坏了。在调试这些接近于硬件层面的问题时,某些奇特的设备有可能给你提供很大的帮助。

有一种通用的工具或许可以派上用场,这就是逻辑分析仪,它能够以每秒数百万次的采样率来捕获、存储并分析数字信号。这些设备原来卖得比汽车还贵,但是现在只要100美元左右就可以买到一台基于USB的逻辑分析仪了。它不仅能够监测主板上面的所有数字信号,而且还能对组件之间进行通信时所采用的一些高层通信协议进行监测。某家制造商(saleae)所出售的产品支持很多种通信协议,其产品信息中罗列了大量的首字母缩略词:“SPI、I2C、serial、1-Wire、CAN、UNI/O、I2S/PCM、MP Mode、Manchester、Modbus、DMX-512、Parallel、JTAG、LIN、Atmel SWI、MDIO、SWD、LCD HD44780、BiSS C、HDLC、HDMI CEC、PS/2、USB 1.1、Midi”。

如果你专门研究某个特定的技术,那么可以考虑购买协议分析仪或总线分析仪等专用的设备。例如,车辆以及其他机器中的微控制器,一般是通过CAN(Controller Area Network,控制器局域网)总线来通信的。有很多公司都在出售那种可以独立运作的分析仪器,把这些仪器插入总线之后,它们就能够对流经总线的数据进行过滤、显示及记录了。对于其他一些使用范围较广或者更加专业化的物理连接方式及协议(如Ethernet、USB、Fibre Channel、SAS、SATA、RapidIO、iSCSI、sFPDP及OBSAI)来说,也有类似的产品可供购买。与基于软件的解决方案相比,这些设备应该能够在其所宣称的线路速率之下工作,而且它们通常可以同时监测多个数据通道,并允许使用者根据位于数据包深处的位模式(bit pattern)来定义触发器与过滤器。

如果没有专门的硬件来进行调试,那么你应该临时打造一个符合自身需求的设备,以帮助你探查那些难以重现的问题。几年前,笔者遇到过这样一个问题:以网页表单的形式所实现的投件箱,可能会丢失数据。这个问题的难处在于:尽管它在数天之间影响了很多用户并招致其抱怨(该程序有成千上万的用户),但是在我们这里,它的出现概率却很低,几乎无法重现。对受影响的用户所在的地方进行分析之后,我们发现这些用户大多位于偏远地区。于是,我们认为问题可能与网络连接的质量有关。我拿了一个USB无线猫,把它用锡纸裹起来,以模拟信号强度较弱的情况,然后通过这个无线猫来连接应用程序的Web界面,这次果然就出现了那个问题,由于该问题已经能够很方便地重现出来(参见第10条),因此只过了几个小时我们就把它解决了。

如果你想调试的代码,是以嵌入式软件的形式来运行的,并且运行该软件的设备又缺乏适当的I/O机制,那么可以考虑采用下面这些技巧来与正在调试的软件进行通信。

  • 如果设备有状态指示灯或能够发出响声,那么可以用特定的闪烁方式或发声方式来表达软件当前的状况。例如,可以用响一声来表示软件进入了某个特定的例程,用响两声来表示软件离开了该例程。你也可以用摩尔斯电码发送更为复杂的消息。
  • 把输出到日志文件中的信息先保存到非易失性的存储器(non-volatile storage)中(甚至可以保存到外接的U盘中),然后将其导入自己的计算机,并对其进行分析。
  • 实现一个简单的串行数据编码器,将数据写入某个尚未使用的I/O针脚,然后对信号进行电平转换,将其转为RS-232标准,并通过串口转USB口的适配器及终端应用程序来在计算机上读取这些数据。
  • 如果设备有网络连接,那么显然可以通过该连接来通信。如果设备缺乏对网络日志(参见第41条)或远程shell访问提供支持的软件,那么可以考虑通过HTTP甚至DNS请求来与外界通信。

要想对网络数据包(network packet)进行监测,就应该先把网络硬件设置好,令其可以接受软件形式的网络包分析器,如开源的Wireshark等。我在笔记本上运行的Wireshark版本支持1514种(网络与USB)协议及数据包类型。如果能把要调试的程序与Wireshark放在同一台计算机中运行,那就可以轻而易举地监测网络数据包了。我们只需要把Wireshark打开,指定自己想要捕获的数据包,然后等着看详细信息就行了。

对两台计算机之间的网络通信(例如,应用程序服务器与数据库服务器或负载均衡器之间的通信)进行监测,或许要显得困难一些。由于这两台计算机可能都要把网线连接到交换机(switch)上面,因此,两个相关端口之间的通信就必须通过交换机才能进行。这个问题可以用很多种办法来解决。

如果你所在的组织使用的是管理型交换机(managed switch,这种交换机比较贵),那么可以对其进行设置,使它把某个端口镜像到另外一个端口上面。也就是说,可以把服务器流量所经过的端口镜像到我们自己的计算机所使用的端口上面,并通过计算机中运行着的Wireshark软件对流经的数据进行捕获及分析。

如果没有这种管理型交换机,那就试着找一台集线器(hub),这种设备比前者便宜很多,它会把接收到的以太网数据广播给所有的端口。由于现在已经不再生产集线器了,因此它通常要比廉价的交换机贵一些。把待监测的计算机和运行着Wireshark软件的计算机连到同一个集线器上面,就可以进行监测。

使用tcpdump这样的命令行工具,也可以对远程主机进行监测。我们需要登录到待监测的远程主机上,并运行tcpdump命令,以查看自己所关注的网络数据包。(该命令需要管理员权限才能执行。)如果还想通过Wireshark的GUI对此进行深入分析,那么可以先用带有-w选项的tcpdump命令将原始数据包写入文件中,然后再通过Wireshark详细地分析它。这种工作方式很适合用来监测基于云端的主机,因为你不太容易去调整其网络配置。

最后一种办法是配置一台计算机,并用该计算机对需要监控的计算机与网络中的其余计算机进行桥接。我们给这台计算机配置两个网络接口(例如,用其中一个接口来表示插有网线的网络端口,用另一个来表示基于USB的端口),并将这两个端口桥接起来。在Linux系统中可以通过brctl命令来实现,在FreeBSD系统中可以通过if_bridge驱动来配置。

此外,我们还可以考虑对设备进行配置,以模拟各种不同的网络场景,例如,可以模拟数据包从世界各地的主机中传过来的情况,或是模拟流量整形(traffic shaping)、带宽限制以及防火墙配置等。此时所需的软件是运行在Linux系统中的iptables。

要点

  • 逻辑分析器、总线分析器或协议分析器可以帮你锁定接近于硬件层面的问题。
  • 可以通过自制的设备来探查与硬件有关的问题。
  • 可以通过将Wireshark与以太网集线器相结合、使用管理型交换机或进行命令行捕获等办法来监测网络数据包。

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

分享:

华章出版社

官方博客
官网链接