strace在項目開發中的一點實踐

在測試中遇到問題或者不合乎期望的情況下,我們第一反應常常是問是不是我們的測試方法,工具,配置或者數據有問題。如果能借助log等手段看到產品運行時的內部,到是可以解答不少疑惑,但是如果不幸(其實是幸運)做的是一個新的產品,還不是完善,包括log,那麼很多時候遇到問題測試人員會覺得很無助,在這個時候我們可能需要藉助一些工具。

strace就是這樣的一個工具,它讓你在沒有源碼,沒有log的情況下可以看到進程運行時的一些“內幕”,只要是系統調用和信號,也就是進程和OS之間打交道的一些過程,也包括數據。我這裏說的限於Linux,其他平臺也有類似的工具,其實strace最早也是源於SunOS (詳細用法和歷史看這裏: http://linux.die.net/man/1/strace

下面用個小小的例子來說明一下使用的情況。
產品需要對網絡包做一些處理,但是如果想明確的指導到底是哪個模塊做了處理(這裏是block),在目前的狀況下還不是很容易,另外也不能排除是測試環境和系統的原因導致包丟失,所以最好的辦法是找到明確的證據。

以下是client端抓包的結果。可以看到在client發出了GET請求之後,沒有收到server端的response,然後重傳了兩次(工具的設置),再次被無視之後發RST自行了斷了。


下面是server端抓包的結果。可以看到server是收到了client的請求,而且也正常回復了(編號12的包),然後server覺得沒有別的東西要傳了,發FIN關了連接,進入半close狀態。接下來發現response沒有發成功,然後重傳了兩次(#15, #16), 發現client端還是沒有響應,然後不得不RST了。



從以上情況可以比較明顯的看出來server的response被中間的設備阻止了,然後這個TCP連接後面的包都不通了。

接下來的問題是誰block了這些包,中間是怎麼處理的。
下面我們用strace進去看一下。
基本的命令是:strace -T -tt -e trace=network [lannch_command]

除了分析這個問題,發現strace可以提供很多的細節,也很有趣。輸出太多,摘錄其中部分。

下面是strace看到的client發起SYN的第一個包。



後面還有兩行:

core_pkt_hook:504: packet #1 passed
core_pkt_allocator_put:126: destroying packet #1

所以可以發現這個包順利通過,然後buf中的數據被刪除。
其實在上面的截圖中,你會發現其實strace的輸出按協議的層次展開的,本來協議棧的處理過程也是這樣。現實ETH層的結果,然後是IP的,TCP的,到payload。層次很清楚,而且數據也幫忙解析出來了,debug很方便。個人覺得,部分程度,甚至可以代替tcpdump和wireshark,如果只是觀察一些很基本的東西,當然包多了或者要看更detail這個是不行的。


接下來是第二個包



嗯,server回的ACK+SYN,順利通過。

好吧,我們直接來看看client一直期待但是沒有收到的第五個包,也就是server的HTTP response。




嗯,看起來沒什麼特別的。但是因爲觸發了一些規則,導致這個包沒有到達client。



從上面的輸出可以很清楚的看到因爲觸發了一些rule,導致這個包被drop了,悄悄的,所以兩邊都不知道,然後各自重傳了。

至此,這個簡單的分析過程就完成了,這樣我們就知道了這個丟包的原因是什麼,是不是按我們期望的,產品真正的work了。而且前提是沒有依賴於任何產品的log和源碼。

這裏監控的只是網絡訪問,其實strace可以監控各種各樣的系統調用。以上只是冰山一角,其實它可以做更多的事情,值得繼續使用和研究。而且還有人寫strace analyzer
http://clusterbuffer.wetpaint.com/page/Strace+Analyzer+-+Previous+Edition


以下是使用過程中的一些小notes。
1. 遇到過以下error
attach: ptrace(PTRACE_ATTACH, ...): Operation not permitted.
後來發現是因爲前一個strace在後臺忘了停掉,再起一次的時候就報這個錯。

2. 結果輸出
strace的信息量很大,全部打到屏幕太多了,可以用-o輸出到問題,或者自己重定向,默認很多是當stderr (也是fd 2)輸出,所以可以 2>&1

3. 有兩種啓動模式,直接啓動被監控的進程,或者-p 來attach到一個正在運行的進程。
理論上兩種模式對於監控應該沒有太大的差別,但是在我的環境裏面,-p模式一直不work,還不清楚爲什麼,可能和我們自己編譯的kernel有關,或者被監控的daemon有什麼特別,還需要研究。同時我試過了4.5.17和4.6兩個版本都是如此,比較費解。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章