天天看點

《Effective Debugging:軟體和系統調試的66個有效方法》——第16條:使用專門的監測及測試裝置

本節書摘來自華章計算機《effective debugging:軟體和系統調試的66個有效方法》一書中的第2章,第16節,作者[希]迪歐米迪斯·斯賓奈裡斯(diomidis spinellis),愛飛翔 譯,更多章節内容可以通路雲栖社群“華章計算機”公衆号檢視。

調試嵌入式系統及系統軟體的時候,我們可能要對從硬體到應用程式的整個計算棧進行分析。調試工作一旦深入硬體層面,我們就需要關注電流的微小變化以及磁矩的對齊情況等細節。在大多數情況下,可以通過強大的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與以太網集線器相結合、使用管理型交換機或進行指令行捕獲等辦法來監測網絡資料包。