gdb: 維持永久的 watchpoint

若想觀察特定變數的變化, watchpoint 比 breakpoint 易於使用。但 watchpoint 有個小問題, 一但離開 scope 後, gdb 會自動刪掉 watchpoint

若該變數是 member field, 就無法持續追踪不同 method 怎麼讀取或寫入它的值。這篇提供一個小技巧, 取用目標變數的指標, 再觀察指標取值的變數, 藉此讓 gdb 認定它不是區域變數, 借用該文的例子如下:

(gdb) p &var1
$1 = (int *) 0x41523c0
(gdb) watch *(int *)0x41523c0
Hardware watchpoint 1: *(int *)0x41523c0

若真的是區域變數的話, 可用 commands 定義簡短的指令, 之後進入函式時, 自動加回 watchpoint, 借用該文提供的例子:

(gdb) break func
(gdb) commands
>   watch var
>   continue
> end

commands 看來很方便, 還有許多適合應用的情境, 像是追踪網路連線輸出關鍵資訊, 可避免手動操作太久造成 timeout。

2012-02-04 更新

gdb 7.4+ 支援 watch -l, 就不用自己取位置再設 watchpoint 解套。在 7.4 之前想用這功能, 可使用 Scott 寫的 gdb-watch-location.py。用法是

$ wget https://raw.github.com/scottt/scottt-gdb/master/gdb-watch-location.py
$ gdb -x gdb-watch-location.py PROG

在 gdb 裡會新增幾個指令: watch-l、rwatch-l、awatch-l 對應到 watch -l、rwatch -l、awatch -l。

留言

  1. 1. 例一中,用 "watch -l var1" 即可 (Stackoverflow 中路人的建議不見得是最好的)

    2. 你 watchpoints 與 commands 都有在用的話,可考慮打開 gdb global history: $HOME/.gdbinit
    set history save on
    set history size 4096
    set history filename /home/fcamel/.gdb_history
    然後像 ipython 一樣,撈 history 寫成 gdb script.

    回覆刪除
    回覆
    1. 原來有watch -l 的用法! 我都還傻傻的印出memory address

      刪除
  2. 查了一下發現是最新的 gdb 7.4 才有的功能, 所以....路人的建議還是實用啦

    回覆刪除

張貼留言

這個網誌中的熱門文章

virtualbox 使用 USB 裝置

熟悉系統工具好處多多

如何 git merge 更改檔名的檔案