2011-12-22 60 views
1

就開源開發而言,我是一個新手。我已經在幾個項目上嘗試過我的手,但由於代碼基數龐大,最終總是感到沮喪。如何使用gdb來剖析像字處理器這樣的應用程序

我一直面臨的一個特殊問題是無法確定大代碼庫的哪個部分處理特定的工作。說,如果我想知道哪部分代碼在文字處理器中進行文本渲染和佈局。

人們經常給出的建議是使用gdb來瀏覽程序。

所以我試圖打開我的文字處理器(這是與調試標誌編譯)的文件,並得到一個回溯,但奇怪的是,我所獲得的是一些普通的函數調用,其中沒有涉及到打開文件。

這是我上執行gdb /usr/local/bin/abiword

(gdb) bt 
0 0xffffe424 in __kernel_vsyscall() 
1 0xb63b472b in poll() from /lib/libc.so.6 
2 0xb66256eb in g_poll() from /usr/lib/libglib-2.0.so.0 
3 0xb6616db6 in ??() from /usr/lib/libglib-2.0.so.0 
4 0xb66174bb in g_main_loop_run() from /usr/lib/libglib-2.0.so.0 
5 0xb6d6668d in gtk_main() from /usr/lib/libgtk-3.so.0 
6 0xb7c04a4d in AP_UnixApp::main (szAppName=0x8048970 "abiword", argc=1, 
    argv=0xbffff704) at ap_UnixApp.cpp:1332 
7 0x080488a3 in main (argc=1, argv=0xbffff704) 
    at ../src/wp/main/gtk/UnixMain.cpp:30 

請建議GDB如何可以用於這種目的而獲得的。對不起,如果我的問題聽起來太不雅觀,但我真的在這樣一個任務的話丟失,所以谷歌也沒有幫助。 :|

+1

你不能隨便選擇一個程序,並運行一個調試器,期望找到一個說明「這部分處理文本的圖形輸出」或其他內容的可讀代碼。除非您在彙編代碼和堆棧跟蹤方面非常先進,否則至少需要調試符號,而使用調試信息和源代碼的目標文件使事情變得更加容易。 – 2011-12-22 23:48:35

+0

謝謝,但我確保使用調試信息編譯程序。 – navgeet 2011-12-22 23:52:25

+0

您可以編輯您的問題並添加該信息。 :) – 2011-12-23 00:12:41

回答

3

人們經常給出的建議是使用gdb來瀏覽程序。

這是最糟糕的可能諮詢,東西打交道時可以複雜到一個字處理器(WP的簡稱)。

您想要做的是在二進制文件上運行ldd,或者在/proc/<pid>/maps上查看正在運行的WP,並查看它使用的共享庫。

然後閱讀有關這些庫。其中一個可能與文本渲染有關。它很可能也帶有一套例子。

構建該庫,構建示例,修改它們以執行其他操作。

現在你準備好回答的問題,如通過設置GDB在庫入口點斷點,並檢查其WP的部分被調用到他們,並與參數「是如何做到這一點WP使用​​該庫」。

重複其他圖書館,你最終將建立一個事情如何融合在一起的圖片。

所以,我想在我的字處理器(這是用調試標誌編譯)打開文件,並得到一個回溯,但奇怪的是,我已經獲得了所有有一些普通的函數調用其中沒有涉及到打開文件。

在GDB中,執行此操作:catch syscall open。現在嘗試打開一個文件,你會發現WP的哪個部分是負責的。

編輯:

「抓系統調用打開」 捕捉所有的 「開放式」 的系統調用,這是很多

是。但WP開始之後不應該有那麼多的open。在屏幕上顯示WP之後,在執行File->Open菜單操作之前,請執行catch

有沒有一種方法可以指定文件的名稱以及catch syscall open?

是的,你可以使catch有條件。條件的細節是特定於操作系統的。看起來你使用的i686-linux與VDSO。對於組合,下面應該做的伎倆:

(gdb) catch syscall open 
Catchpoint 1 (syscall 'open' [5]) 

(gdb) cond 1 ((char*)$ebx)[0] == '/' && ((char*)$ebx)[1] == 'h' \ 
      && ((char*)$ebx)[2] =='o' && ((char*)$ebx)[3] == 'm' 

以上情況會使捕獲點只開有"/hom"前綴的文件時停止。

您可以通過明顯的方式添加更多字母。

你也可以試試這個:

(gdb) cond 1 0 == strcmp($ebx, "/home/nav/Doc1.doc") 

,但你到main在此之前將有可能無法正常工作,從而可能導致崩潰GDB(墜毀我的,這是一個bug)。

+0

「捕獲系統調用打開」捕獲所有「打開」系統調用,這是很多。有沒有一種方法來指定文件的名稱以及catch syscall open? 我在程序上運行strace並打開一個示例文件。這是其中一個呼叫: open(「/ home/nav/Doc1.doc」,O_RDONLY | O_LARGEFILE) 我想知道在這個調用中我是否可以在gdb中斷開。 – navgeet 2011-12-23 21:42:44

+0

奇怪的是,當我在gdb 7.2 p1上試過cond 1 0 == strcmp($ ebx,「/home/nav/Doc1.doc」)時,我也收到了一個分段錯誤。 奇怪的是當我用--enable-debug詮釋gdb 7.3.1時我收到: 測試斷點條件時出錯: 當前上下文中沒有符號「strcmp」。 Catchpoint 1(調用syscall'open'),0xb7ff85b4在?? () from /lib/ld-linux.so.2 – navgeet 2011-12-24 03:04:38

+0

@navgeet「沒有符號strcmp」...這就是「在你到達」主「部分之前不會工作 – 2011-12-24 03:11:35

相關問題