利用strace/pstack除錯Nginx
Linux下有兩個命令strace 和ltrace 可以檢視一個應用程式在執行過程中所發起的系統呼叫,這對作為標準應用程式的Nginx自然同樣可用。由於這兩個命令大同小異,所以下面就僅以strace為例做簡單介紹,大致瞭解一些它能幫助我們獲取哪些有用的除錯資訊。關於strace/ltrace以及後面介紹的pstack更多的用法請參考對應的Man手冊。
從strace的Man手冊可以看到幾個有用的選項。
-p pid:通過程式號來指定被跟蹤的程式。
-o filename:將跟蹤資訊輸出到指定檔案。
-f:跟蹤其通過frok呼叫產生的子程式。
-t:輸出每一個系統呼叫的發起時間。
-T:輸出每一個系統呼叫消耗的時間。
首先利用ps命令檢視到系統當前存在的Nginx程式,然後用strace命令的-p選項跟蹤Nginx工作程式,如圖2-2所示。
為了簡化操作,我這裡只設定了一個工作程式,該工作程式會停頓在epoll_wait系統呼叫上,這是合理的,因為在沒有客戶端請求時,Nginx就阻塞於此(除非是在爭用accept_mutex鎖),在另一終端執行wget命令向Nginx發出http請求後,再來看strace的輸出,如圖2-3所示。
[root@localhost ~]# wget 127.0.0.1
通過strace的輸出可以看到Nginx工作程式在處理一次客戶端請求過程中發起的所有系統呼叫。我這裡測試請求的html非常簡單,沒有附帶css、js、jpg等檔案,所以看到的輸出也比較簡單。strace輸出的每一行記錄一次系統呼叫,等號左邊是系統呼叫名以及呼叫引數,等號右邊是該系統呼叫的返回值。逐一註釋如下所述。
1. epoll_wait返回值為1,表示有1個描述符存在可讀/寫事件,這裡當然是可讀事件。
2. accept4接受該請求,返回的數字3表示socket的檔案描述符。
3. epoll_ctl把accept4建立的socket套接字(注意引數3)加入到事件監聽機制裡。
4. recv從發生可讀事件的socket檔案描述符內讀取資料,讀取的資料存在第二個引數內,讀取了107個位元組。
5. stat64判斷客戶端請求的html檔案是否存在,返回值為0表示存在。
6. open/fstat64開啟並獲取檔案狀態資訊。open檔案返回的檔案描述符為9,後面幾個系統呼叫都用到這個值。
7. writev把響應頭通過檔案描述符3代表的socket套接字發給客戶端。
8. sendfile64把檔案描述符9代表的響應體通過檔案描述符3代表的socket套接字發給客戶端。
9. 再往檔案描述符4代表的日誌檔案內write一條日誌資訊。
10. recv看客戶端是否還發了其他待處理的請求/資訊。
11. 最後關閉檔案描述符3代表的socket套接字。
由於strace能夠提供Nginx執行過程中的這些內部資訊,所以在出現一些奇怪現象時,比如Nginx啟動失敗、響應的檔案資料和預期不一致、莫名其妙的Segment Fault段錯誤、存在效能瓶頸(利用-T選項跟蹤各個函式的消耗時間),利用strace也許能提供一些相關幫助。最後,要退出strace跟蹤,按ctrl+c即可。
命令strace跟蹤的是系統呼叫,對於Nginx本身的函式呼叫關係無法給出更為明朗的資訊,如果我們發現Nginx當前執行不正常,想知道Nginx當前內部到底在執行什麼函式,那麼命令pstack就是一個非常方便實用的工具。
pstack的使用也非常簡單,後面跟程式ID即可。比如在無客戶端請求的情況下,Nginx阻塞在epoll_wait系統呼叫處,此時利用pstack檢視到的Nginx函式呼叫堆疊關係,如圖2-4所示。
從main()函式到epoll_wait()函式的呼叫關係一目瞭然,和在gdb內看到的堆疊資訊一模一樣,其實因為命令pstack本身也就是一個利用gdb實現的shellShell指令碼,關於這點,感興趣的讀者可以自己看下pstack對應的指令碼程式。
via http://book.51cto.com/art/201305/395383.htm
相關文章
- 除錯跟蹤利器---strace除錯
- nginx 錯誤除錯Nginx除錯
- 除錯 Ingress Nginx除錯Nginx
- pstack
- 反除錯&反反除錯 -- 利用sysctl檢測偵錯程式是否存在除錯
- 反除錯 -- 利用ptrace阻止偵錯程式附加除錯
- 利用whistle除錯websocket和socket請求除錯Web
- 利用whistle除錯移動端頁面除錯
- Nginx R31 doc-17-debugging 除錯Nginx除錯
- 利用VS2017編譯、除錯Linux程式編譯除錯Linux
- 利用 Valet 開發和除錯 PHP 專案除錯PHP
- 利用Visual Studio除錯WSL下的C++工程除錯C++
- 利用QEMU+GDB搭建Linux核心除錯環境Linux除錯
- 除錯篇——除錯物件與除錯事件除錯物件事件
- Windows windbg kernel debug 雙機核心除錯 - USB3.0 除錯 USB除錯 除錯線Windows除錯
- Python 程式碼除錯—使用 pdb 除錯Python除錯
- IsDebuggerPresent的反除錯與反反除錯除錯
- find 命令刪除冗餘 Nginx 錯誤日誌並實現備份Nginx
- 造輪子-strace(一)
- 前端除錯前端除錯
- python 除錯Python除錯
- LLDB除錯LLDB除錯
- postman除錯Postman除錯
- Linux除錯Linux除錯
- 除錯toybox除錯
- gdb除錯除錯
- 作業系統診斷工具truss, pstack, and pmap作業系統
- 利用ABAP除錯模式修改SE16裡資料庫表的內容除錯模式資料庫
- [20181217]strace使用問題.txt
- 【除錯】SystemTap除錯網路卡狀態一例除錯
- .NET高階除錯系列-Windbg除錯入門篇高階除錯
- windows 中nginx奇葩報錯 nginx: [emerg] unknown directive "#" in nginx/conf/nginx.conf:3WindowsNginx
- win10 如何除錯串列埠_win10串列埠除錯怎麼除錯Win10除錯串列埠
- vscode使用chrome除錯報錯VSCodeChrome除錯
- console 除錯技巧除錯
- Express 文件(除錯)Express除錯
- Chrome 除錯技巧Chrome除錯
- console除錯命令除錯
- css除錯技巧CSS除錯