Ads 468x60px

##EasyReadMore##

09 9月, 2016

用 strace、lsof 除錯程序

在理想世界裡,每當一個程序不能正常執行一個功能時,它就會給出一個有用的錯誤提示,告訴你在足夠的改正錯誤的線索。但有時候一個程序出現了問題,你無法找到原因。

這就是除錯程序出現的原因。 strace是一個必不可少的除錯工具,strace用來監視系統呼叫。你不僅可以除錯一個新開始的程序,也可以除錯一個已經在運行的程序(把 strace 綁定到一個已有的 PID 上面)。首先讓我們看一個真實的例子:

用 strace 看一下在啟動 dcopserver 時到底程序做了什麼:
strace -f -F -o ~/dcop-strace.txt dcopserver
# -o filename: 將 strace 的輸出寫入文件 filename
# -f 跟踪由fork呼叫所產生的子進程.
# -F 嘗試跟踪vfork呼叫.在-f時,vfork不被跟踪.

view plaincopy to clipboardprint?
27207 mkdir("/tmp/.ICE-unix", 0777) = -1 EEXIST (File exists)
27207 lstat64("/tmp/.ICE-unix", {st_mode=S_IFDIR|S_ISVTX|0755, st_size=4096, ...}) = 0
27207 unlink("/tmp/.ICE-unix/dcop27207-1066844596") = -1 ENOENT (No such file or directory)
27207 bind(3, {sin_family=AF_UNIX, path="/tmp/.ICE-unix/dcop27207-1066844596"}, 38) = -1 EACCES (Permission denied)  
27207 write(2, "_KDE_IceTrans", 13) = 13
27207 write(2, "SocketCreateListener: failed to "..., 46) = 46
27207 close(3) = 0 27207 write(2, "_KDE_IceTrans", 13) = 13
27207 write(2, "SocketUNIXCreateListener: ...Soc"..., 59) = 59
27207 umask(0) = 0 27207 write(2, "_KDE_IceTrans", 13) = 13
27207 write(2, "MakeAllCOTSServerListeners: fail"..., 64) = 64
27207 write(2, "Cannot establish any listening s"..., 39) = 39

其中第一行顯示程序試圖創建/tmp/.ICE-unix目錄,權限為0777,這個操作因為目錄已經存在而失敗了。第二個系統呼叫(lstat64)檢查了目錄狀態,並顯示這個目錄的權限是0755,這裡出現了第一個程序運行錯誤的線索:程序試圖創建屬性為0777的目錄,但是已經存在了一個屬性為0755的目錄。第三個系統呼叫(unlink)試圖刪除一個文件,但是這個文件並不存在。這並不奇怪,因為這個操作只是試圖刪掉可能存在的老文件。

但是,第四行確認了錯誤所在。他試圖綁定到 /tmp/.ICE-unix/dcop27207-1066844596,但是出現了拒絕訪問錯誤。 . ICE_unix 目錄的用戶和組都是 root,並且只有所有者俱有寫權限。一個非 root 用戶無法在這個目錄下面建立文件,如果把目錄屬性改成 0777,則前面的操作有可能可以執行,而這正是第一步錯誤出現時進行過的操作。

所以我運行了 chmod 0777 /tmp/.ICE-unix 之後 KDE 就可以正常啟動了,問題解決了,用 strace 進行跟踪除錯只需要花很短的幾分鐘時間跟踪程序運行,然後檢查並分析輸出文件。

lsof -p 3125

查看進程 3125 打開了哪些文件

COMMAND    PID USER   FD   TYPE  DEVICE SIZE/OFF   NODE NAME
RuleEngin 1905 root  cwd    DIR   252,0     4096 128348 /opt/agent/exe/RuleEngine
RuleEngin 1905 root  rtd    DIR   252,0     4096      2 /
RuleEngin 1905 root  txt    REG   252,0    69536 128418 /opt/agent/exe/RuleEngine/RuleEngine.out
RuleEngin 1905 root  mem    REG   252,0   139552 121119 /lib/ld-2.20.so
RuleEngin 1905 root  mem    REG   252,0  1548920 120981 /lib/libc-2.20.so
RuleEngin 1905 root  mem    REG   252,0    98684 120304 /lib/libpthread-2.20.so
RuleEngin 1905 root  mem    REG   252,0    15576 121112 /lib/libdl-2.20.so
RuleEngin 1905 root  mem    REG   252,0    40992 172432 /usr/lib/libjson-c.so.2.0.1
RuleEngin 1905 root  mem    REG   252,0    32476 120973 /lib/librt-2.20.so
RuleEngin 1905 root  mem    REG   252,0   863800 172441 /usr/lib/libsqlite3.so.0.8.6
RuleEngin 1905 root    0u   CHR  188,99      0t0   8013 /dev/ttyUSB99
RuleEngin 1905 root    1u   CHR  188,99      0t0   8013 /dev/ttyUSB99
RuleEngin 1905 root    2u   CHR  188,99      0t0   8013 /dev/ttyUSB99
RuleEngin 1905 root    3r   REG    0,13       80  17663 /cmd_queue
RuleEngin 1905 root    4u  IPv4 2145014      0t0    TCP *:8591 (LISTEN)
RuleEngin 1905 root    5u   REG   252,0    14336 128391 /opt/agent/exe/RuleEngine/ruleEgine.db3

可以看到用到了哪些 lib、佔用 port、使用的資料庫

source:

程式扎記: [Linux 文章收集] strace 命令用法 - http://goo.gl/sXaV9R

0 意見:

張貼留言

 
Blogger Templates