2012年2月16日 星期四

配合 c++filt 讀程式

在用 gdb 追蹤程式前, 得先找到幾個關鍵中斷點, 才能著手進行。若有機會想到不錯的關鍵字的話, 除了用 grep 之類的工具大海撈針外, 有時從 binary 裡下手, 效果也不錯, 有機會減少搜尋範圍。畢竟程式碼中難免有一些平台或參數相關的設定, 讓部份程式碼根本沒有編進 binary。從 binary 回頭找, 可免除這層顧慮。

我目前試過的作法有兩種

  • string PROG | grep KEYWORD
  • nm PROG | grep KEYWORD | awk '{print $NF}' | xargs c++filt

第一個作法是配合程式輸出的訊息來找程式。

第二個作法則是從 binary 取出可能有關的的 symbol, 再用 c++filt demangle symbol, 找出它的 namespace、signature 等資訊。需要注意的是, 有可能因編譯器最佳化 (如 inline), 實際上沒有呼叫到函式。經 qrtt1 提醒, 保險起見, 可在編譯時加上 -O0 確保行為符合預期。

題外話, C 的 function name 反而無法 demangle 找出 signature(應該沒理解錯吧)。不過相對於 C++ 的複雜度, 讀 C 的程式時, 也許沒那麼需要吧。

2 則留言:

  1. -O0 -g3 會變出更多 debug 資訊

    以下是來自 gcc 文件的說明
    -g

    ...
    Level 3 includes extra information, such as all the macro definitions present in the program. Some debuggers support macro expansion when you use -g3.

    預設只有 -g2 而已

    回覆刪除
  2. 謝啦, 之後有需求時來試看看, 之前挺多只有用 gcc -dD -E 來看巨集定義的常數

    回覆刪除

在 Fedora 下裝 id-utils

Fedora 似乎因為執行檔撞名,而沒有提供 id-utils 的套件 ,但這是使用 gj 的必要套件,只好自己編。從官網抓好 tarball ,解開來編譯 (./configure && make)就是了。 但編譯後會遇到錯誤: ./stdio.h:10...