事例4

这儿举另外一个不会造成明显故障或性能问题的事例。系统看起来是正常的,但当程序员运行某个视图线迹来查看它是什么问题的时候,线迹表明存在若干非同寻常量的未锁运行,它们当中大部分以紧密组出现,除了第一个返回一个错误信息外,总共有10个快速进行的未锁系统调用。

原因是由于将多用户计算机操作系统(UNIX)接入这一程序的人员没有注意到:他在使用了计数旗语的原程序上使用了二进制旗语。如果在一段程序当中几次出现未锁系统调用,二进制旗语不会有任何释放。程序与二进制旗语一起运行,但是旗语正在管理的队列决不会仅由一个入口填满。系统上下软件之间切换过频,达到大约10次,但仍在性能要求范围内,当二进制旗语被某个计数旗语代替时,系统运行更为良好(至少看起来如此)。

事例5

HawkEye线迹含有我正在寻找的问题的完好信息,而且完全朝向线迹未端,像一个蹩脚楔子,图2将这个楔子放大,我发现它是由均在同一个事件上的约一百个左右的事件设置系统调用组成的,尽管这些事件设置组合释放了一个事件等待。麻烦的是这个事件设置系统调用中的某一个可能足以释放等待任务。这发生于一个到伪-TTY装置的写调用的底部(远程登陆对话应用这些来实现类似终端的槽连接)。这个伪-TTY的终端部分正应用事件来控制装置插槽端的数据搬移,它为每一个特征设置事件,因此,我确信我已经找到了问题所在。

虽然这个线迹显示了问题所在,但实际情况却不是。它是一种相对简单的界面的图形描述,这一界面位于某一个特征装置和某一个数据包装置之间。通过让每一特征上的操作系统上下文切换,通信速度可减慢到约300bps,从而确定问题所在。以每一线而非每一个特征来设置事件听起来不失为一个好主意,但伪-TTY并非以线为导向,一次发送一条线会像全屏编辑器那样中断程序。

有时候正确的实现方案看起来却很别扭。

经验教训图 2: HawkEye线迹含有正在被寻找的问题的完好信息。

上述事例表明:视图工具能够发现在完全调试过的软件当中所存在的许多问题。当它专用于查找特殊故障的原因时,它从不会出错,此外,它似乎也能够发现像程序员正在寻找的问题。后两类在我们的记录文件中占主要部分。程序员遇到的问题能够全部由软件的单步运行或通过使程序中断来彻底来加以查明。它们不是视图工具要解决的具有奇怪竞争条件的问题,这些问题的发现是由于视图工具使其更加容易地搜集在系统执行过程中的数据,从而使工程师能够利用大脑的图形检测能力对问题进行分析。

我很想知道,上述事例是否代表了嵌入式领域以外的问题。也许我一直在紧张的CPU和存储器预算中工作的太久,以至于丧失了自己的看法,在此,大部分意外事例都同仅遭受性能问题的系统有关。此类例子还很多,例如:
1. 某个程序会一个接一个的分配成打的小的存储块,此后这些存储块将按序释放出来。没有理由说明对所有这些结构,这个程序不会分配某一个邻近的存储块。
2. 某个程序一遍遍分配并立即释放某个存储块,但是它应当只分配和释放一次。
3. 某个程序多次打开并关闭文件。
4. 另一个程序多次打开某个文件却未关闭它。
5. 某个程序反复对信号掩码,然后以相同的次数去掉信号的掩码。
6. 某个程序尝试返回某个未知服务错误的系统调用,并立即再次尝试调用。

上述行为在桌面或主机软件中是可接受的吗?对于嵌入式实时程序员而言,或许视图工具比其它程序员有价值得多。

我一直在设计和使用视图工具,好像他们是软件的逻辑分析仪。这一工具收集并显示围绕某一特定问题执行时的细节。这是一个重要的应用,但工具也显示了在软件执行时的高级图形模式。用户的事例告诉我们:程序员应当用每一种可用的工具来检查他们的产品,而且我们还需要更多和更好的工具来观察软件的运行情况。

我期望用户的事例将揭示:HawkEye需要收集和显示更多的资料,而且它还需要更复杂的触发点。我明白这一点,但是,我不会采取与我的用户相同的方式。他们正应用HawkEye作为观察软件黑盒子内部为简便的手段,可以自豪地说,HawkEye在查找问题的过程中正在发挥作用。