Linux 調試三劍客——strace,lsof,tcpdump

歡迎分享,微博 老和山小范 ,博客 wsfdl.com

Brendan D. Gregg 專注 Linux performance & tuning 許多年,其博客 brendangregg.com 裏關於分析和調優的乾貨琳琅滿目。一篇名爲 Linux Performance 文章全面而詳細的整理了常用工具,覆蓋了硬件、存儲、網絡乃至應用,如下圖:

Linux performance

能掌握上圖的十八般武藝固然最好,從定位分析的角度來說,我認爲三個高級而常用的命令是 strace, lsof 和 tcpdump。


strace

strace - trace system calls and signals

據說,對一個經驗豐富的 Linux C/C++ 工程師,他通過 strace 即可分析多數軟件的大致實現方式。Linux 進程空間可分爲用戶空間和內核空間,程序通常運行在用戶態,它需要通過 系統調用 訪問內核空間。系統調用的重要性不言而喻,凡是涉及到進程、文件管理、設備管理和通信等的操作都必須依賴系統調用完成,如下:

  • Process Control: load/execute/end/abort/create/terminate process, get/set process attributes, wait for time/event/signal, allocate/free memory
  • File management: create/delete/open/read/write/reposition file, get/set file attributes
  • Device Management: request/release/attach/detach device,read/write/reposition, get/set device attributes
  • Communication: create/delete connection, send/receive messages, transfer status information

strace 追蹤進程產生的所有系統調用,包括參數、返回值和執行消耗的時間,很多是涉及到內核和資源層面的操作都需要系統調用完成,所以 strace 在診斷以下場景非常有效:

  • 程序意外退出
  • 程序運行緩慢
  • 進程阻塞

strace 的通常使用方式如下:

strace -f -F -T -tt -o output.txt straced_cmd

-f  跟蹤 fork 產生的子進程
-F  跟蹤 vfork 產生的子進程
-tt 在輸出中的每一行前加上時間信息,微秒級
-T  顯示每一個調用所耗的時間
-o  輸出到指定文件 output.txt

例如:

$ strace -T -tt -f -F ls
14:17:18.096447 execve("/bin/ls", ["ls"], [/* 31 vars */]) = 0 <0.000191>
14:17:18.097156 brk(0)                  = 0x1852000 <0.000196>
14:17:18.097554 access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory) <0.000088>
14:17:18.097836 mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f6056b52000 <0.000186>
14:17:18.098242 access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory) <0.000097>
14:17:18.101519 open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3 <0.000131>

對於守護進程,strace 的使用爲:

strace -T -tt -e trace=all -o output.txt -p daemon_pid

lsof

Unix philosophy: everything is a file.

Linux/Unix 的文件類型有以下 7 種:

  • Regular file
  • Directory
  • Symbolic link
  • Named pipe
  • Socket
  • Device file
  • Door

lsof 用於查看進程打開的文件,使用方式如下:

# 查看某個進程打開的文件
lsof -p pid

# 查看某個文件被哪些進程打開
lsof file_name

例如:

# 1250 爲 nova-api 的 pid
$ lsof -p 1250
COMMAND   PID USER   FD   TYPE DEVICE SIZE/OFF   NODE NAME
nova-api 1250 nova  cwd    DIR  252,0     4096 133223 /var/lib/nova
nova-api 1250 nova  rtd    DIR  252,0     4096      2 /
nova-api 1250 nova  txt    REG  252,0  3345416 274069 /usr/bin/python2.7
nova-api 1250 nova  mem    REG  252,0    31720 407980 /usr/lib/python2.7/dist-packages/Crypto/Cipher/_AES.x86_64-linux-gnu.so
......
nova-api 1250 nova    5w  FIFO    0,9      0t0  12796 pipe
nova-api 1250 nova    6u  IPv4  12864      0t0    TCP *:8773 (LISTEN)
nova-api 1250 nova    7u  IPv4  12891      0t0    TCP *:8774 (LISTEN)
nova-api 1250 nova    8r   CHR    1,9      0t0   6683 /dev/urandom
nova-api 1250 nova    9u  IPv4  12986      0t0    TCP *:8775 (LISTEN)
nova-api 1250 nova   17u  0000   0,10        0   6631 anon_inode~ bash

又如,查詢 /var/log/nova/nova-api 被哪些進程打開:

$ lsof /var/log/nova/nova-api.log
COMMAND   PID USER   FD   TYPE DEVICE SIZE/OFF   NODE NAME
nova-api 1250 nova    3w   REG  252,0  2086779 133272 /var/log/nova/nova-api.log
nova-api 2235 nova    3w   REG  252,0  2086779 133272 /var/log/nova/nova-api.log
nova-api 2247 nova    3w   REG  252,0  2086779 133272 /var/log/nova/nova-api.log
nova-api 2255 nova    3w   REG  252,0  2086779 133272 /var/log/nova/nova-api.log

tcpdump

tcpdumpwireshark 類似,都是抓包工具,windows 用戶多用 wireshark,linux 用戶多用 tcpdump。tcpdump 允許用戶攔截和顯示發送或收到過網絡連接到該計算機的TCP/IP和其他數據包,從數據鏈路層、網絡層、傳輸層乃至應用層,覆蓋了多種常用協議,並提供了豐富的過濾功能,使用如下:

過濾網卡:

tcpdump -i eth1

過濾 IP:

tcpdump net 10.10.10.1
tcpdump src net 10.10.10.1
tcpdump dst net 10.10.10.2

過濾 port:

tcpdump port 80
tcpdump src port 80
tcpdump dst port 80

過濾 protocol:

tcpdump arp
tcpdump icmp
tcpdump ip
tcpdump udp
tcpdump tcp

常用表達試:

&  or 'and'
|| or 'or'
!  or 'not'

抓取所有經過 eth0,目的地址是 10.10.10.1:80 的 TCP 數據:

$ tcpdump -i eth0 (tcp) and (dst port 80) and (dst net 10.10.10.1)  
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章