當(dāng)一個(gè)程序發(fā)生故障時(shí),有時(shí)候想通過了解該進(jìn)程正在執(zhí)行的系統(tǒng)調(diào)用來排查問題。通常可以用 strace 來跟蹤。但是當(dāng)進(jìn)程已經(jīng)處于 D 狀態(tài)(uninterruptible sleep)時(shí),strace 也幫不上忙。這時(shí)候可以通過
D 狀態(tài)實(shí)際是在等待系統(tǒng)調(diào)用返回。那么來看看究竟在等待什么系統(tǒng)調(diào)用
第一個(gè)數(shù)字是系統(tǒng)調(diào)用號,后面是參數(shù)。不同的系統(tǒng)調(diào)用所需的參數(shù)個(gè)數(shù)不同。這里的字段數(shù)是按最大參數(shù)數(shù)量來的,所以不一定每個(gè)參數(shù)字段都有價(jià)值。那么怎么知道系統(tǒng)調(diào)用號對應(yīng)哪個(gè)系統(tǒng)調(diào)用呢?在頭文件 /usr/include/asm/unistd_64.h 中都有定義。也可以用個(gè)小腳本來快速查找:
對于不同的系統(tǒng)調(diào)用的參數(shù),可以通過 man 2 <系統(tǒng)調(diào)用名> 查閱。如 man 2 read。對剛才那個(gè)例子來說,0 就對應(yīng)了 read 調(diào)用。而 read 調(diào)用的第一個(gè)參數(shù)是文件描述符。
之后用 lsof 找到 7 對應(yīng)的是什么文件
結(jié)果發(fā)現(xiàn)是個(gè) device mapper 的設(shè)備文件。最后順藤摸瓜,發(fā)現(xiàn)這個(gè)文件是 multipathd 創(chuàng)建的。而系統(tǒng)應(yīng)當(dāng)使用的是存儲廠商提供的多路徑軟件。問題是由于同時(shí)開啟了 multipathd 造成沖突導(dǎo)致的。
/proc/<PID>/syscall 對排查 D 狀態(tài)進(jìn)程很有用。不過在 2.6.18 內(nèi)核上并不支持,具體從哪個(gè)內(nèi)核版本開始有這個(gè)功能,還沒查到。不過至少從在 2.6.32 以上版本都是支持的。
新聞熱點(diǎn)
疑難解答
圖片精選