使用watch來監控內存

衆所周知,在所有的邏輯Bug中,野指針或者數組越界引起的Bug最難調,因爲暴露問題的地方與真正產生問題的地方往往不是在同一個地方,而且這種Bug往往具有隨機性,讓人頭痛。

調上述Bug的標準做法就是使用GDB的watch命令來監控內存變化,當watch的內存發生變化時,調試程序會停住,我們就知道是哪一步動了“奶酪”。

watch的使用也很簡單,如果有一個指針pTest指向一塊內存,則:

  • watch pTest 監控pTest指針變量本身,如果pTest中存儲的內存地址發生變化,調試程序停住
  • watch *pTest 監控pTest所指向的內存(*pTest本身就是一個地址數據),如果這塊內存發生變化,調試程序停住

其中watch *pTest的形式往往更常用

但在使用watch的時候會常常遇到如下問題:

https://stackoverflow.com/questions/4702638/gdb-watch-pointer-giving-too-many-h-w-watchpoints-error

https://stackoverflow.com/questions/3470704/setting-gdb-hardware-watchpoint-how-to-set-software-watchpoint

(gdb) watch val_msgs[0]->val
Hardware watchpoint 2: this->val_msgs[0]->val
(gdb) c
Continuing.
pingCharmrun (ignored=0x7ffff73751c1) at machine.c:1151
1151    {
Current language:  auto; currently c
(gdb) c
Continuing.
Warning:
Could not insert hardware watchpoint 2.
Could not insert hardware breakpoints:
You may have requested too many hardware breakpoints/watchpoints.

最後一行說設置了太多硬件斷點或者watch點,但實際上只設置了一個watch點,這其實是調試寄存器不夠用造成的,有如下兩種方案可以解決:

  1. 減少監控對象。我發現可以用全局指針來指向想監控的內存,然後watch全局指針,這樣就不會報錯,但是並不明白其中原理。
  2. 其實也不用這麼麻煩,標準解決方案是在GDB中:
    set can-use-hw-watchpoints 0

    就是將硬件watch點設置爲0,這樣GDB會使用軟件watch點,這當然比硬件watch點要慢,但是不影響GDB使用,更重要的是watch點可以放開用了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章