2010/10/12

printf debug 大法?改用 gdb 取代 printf debug 方式

這個東西 jserv 在好久以前的演講就提過,不過今天要用又找了一會才找到,筆記與此。

很多時候在 debug 的時候只是要確定程式跑到那段時,大概有很大的機率會加入 printf 到程式碼裡面來進行這樣的 debug 動作。不過使用 printf 每次都要重新編譯源碼實在是有點麻煩,而使用 gdb print 資訊可以在不更動源碼也不會有每次都因為設定中斷點就停下來的問題。

比如說有以下程式:
switch (m_punct_mode) {
    case MODE_DISABLE:
        {
            g_assert (ch == IBUS_grave);
            ...
            update ();
        }
        break;
    case MODE_INIT:
        {
            m_text.clear ();
            ...
            m_cursor = 0;
        }
    case MODE_NORMAL:
        {
            m_text.insert (m_cursor, ch);
            ...
            update ();
        }
        break;
    default:
        g_assert_not_reached ();
    }

我們想在程式運行時知道到底跑到那個 switch case, 就可以用 gdb 來 print。其中的原理是利用中斷之後執行一小段 gdb 命令來達成。gdb 有個指令叫做 commands 可以在中斷後自動執行一小段 gdb 指令,所以如果我們使用 command 指令再配合 print 以及 continue 就可以做出類似 printf 的除錯功能。比如說第一個中斷點的設定方式則為:

b editor.cc:4
commands
print "MODE_DISABLE"
continue
end

這樣執行時就可以讓 gdb 印出資訊達到 printf 的效果,但卻不用重新編譯源碼。

3 則留言 :

  1. 工程師應該隨專案準備一些 gdb macro,這樣可大幅縮減除錯時間 :)

    回覆刪除
  2. 確實,這個功能超好用的
    不過輸入法除錯的時候常常會 break/continue 之後就當機

    回覆刪除
  3. 可以先啟動一個 Xephyr ( http://www.freedesktop.org/wiki/Software/Xephyr ),假設是 DISPLAY=:99 , 那麼只要輸入法也是跑在 DISPLAY=:99 的環境,那衝擊就會小一些

    回覆刪除