gdb 是 linux 系統上常用的 c/c++ 除錯工具,功能十分強大。對於較為複雜的系統,比如多程序系統,如何使用 gdb 除錯呢?考慮下面這個三程序系統:
proc2 是 proc1 的子程序,proc3 又是 proc2 的子程序。如何使用 gdb 除錯 proc2 或者 proc3 呢?
實際上,gdb 沒有對多程序程式除錯提供直接支援。例如,使用gdb除錯某個程序,如果該程序fork了子程序,gdb會繼續除錯該程序,子程序會不受干擾地執行下去。
如果你事先在子程序**裡設定了斷點,子程序會收到sigtrap訊號並終止。那麼該如何除錯子程序呢?其實我們可以利用gdb的特點或者其他一些輔助手段來達到目的。此外,gdb 也在較新核心上加入一些多程序除錯支援。
(1)attach子程序
眾所周知,gdb有附著(attach)到正在執行的程序的功能,即attach 命令。因此我們可以利用該命令attach到子程序然後進行除錯。
例如我們要除錯某個程序rim_oracle_agent.9i,首先得到該程序的pid
[root@tivf09 tianq]# ps -ef|grep rim_oracle_agent.9i通過pstree可以看到,這是乙個三程序系統,oserv是rim_oracle_prog的父程序,rim_oracle_prog又是rim_oracle_agent.9i的父程序。nobody 6722 6721 0 05:57 ? 00:00:00 rim_oracle_agent.9i
root 7541 27816 0 06:10 pts/3 00:00:00 grep -i rim_oracle_agent.9i
[root@tivf09 root]# pstree -h 6722通過 pstree 察看程序
啟動gdb,attach到該程序
用 gdb 連線程序
現在就可以除錯了。乙個新的問題是,子程序一直在執行,attach上去後都不知道執行到**了。有沒有辦法解決呢?
乙個辦法是,在要除錯的子程序初始**中,比如main函式開始處,加入一段特殊**,使子程序在某個條件成立時便迴圈睡眠等待,attach到程序後在該**段後設上斷點,再把成立的條件取消,使**可以繼續執行下去。
至於這段**所採用的條件,看你的偏好了。比如我們可以檢查乙個指定的環境變數的值,或者檢查乙個特定的檔案存不存在。以檔案為例,其形式可以如下:
void debug_wait(char *tag_file)當attach到程序後,在該段**之後設上斷點,再把該檔案刪除就ok了。當然你也可以採用其他的條件或形式,只要這個條件可以設定/檢測即可。}
attach程序方法還是很方便的,它能夠應付各種各樣複雜的程序系統,比如孫子/曾孫程序,比如守護程序(daemon process),唯一需要的就是加入一小段**。
如果你是在一台遠端linux伺服器上除錯,那麼可以使用vnc(virtual network computing) viewer從本地機器連線到伺服器上使用xterm。在此之前,需要在你的本地機器上安裝vnc viewer,在伺服器上安裝並啟動vnc server。大多數linux發行版都預裝了vnc-server軟體包,所以我們可以直接執行vncserver命令。注意,第一次執行vncserver時會提示輸入密碼,用作vnc viewer從客戶端連線時的密碼。可以在vnc server機器上使用vncpasswd命令修改密碼。
gdb除錯正在執行的程序
有時會遇到一種很特殊的除錯需求,對當前正在執行的其它程序進行除錯 正是我今天遇到的情形 這種情況有可能發生在那些無法直接在偵錯程式中執行的程序身上,例如有的程序 只能在系統啟動時執行。另外如果需要對程序產生的子程序進行除錯的話,也只能採用這種方式。gdb可以對正在執行的程式進行排程,它允許開發人員中...
gdb除錯正在執行程序
用gdb可以除錯當前的程式的使用情況,讀出他的引數。以下用乙個簡單的程式做為例子 來說明gdb的除錯。第一步 編譯乙個死迴圈程式。file name malloc.c include include include void getmem void p,int num void test void ...
gdb用法(三) 除錯其他正在執行的程序
有時會遇到一種很特殊的除錯需求,對當前正在執行的其它程序進行除錯。這種情況有可能發生在那些無法直接在偵錯程式中執行的程序身上,例如有的程序只能在系統啟動時執行。另外如果需要對程序產生的子程序進行除錯的話,也只能採用這種方式。gdb可以對正在執行的程式進行排程,它允許開發人員中斷程式並檢視其狀態,之後...