robot
最新文章(10)
Mqskit 和其它相關工具
CPython 的 GC 二、三事
寫 Mecurial Extension 是件快樂的事!
Mozilla 台灣辨公室徵人啟事
關於 Apple 的兩項專利
core dump 之前的 frame
怎麼發出 beep 聲?
先承認你要找的是奴才吧!
程式碼要清的多乾淨?
FreeBSD 的 Thread-Local Storage 實作
首頁
新編
最新留言
Entries RSS
重要關鍵字(10)
coding (122)
Python (93)
FreeBSD (71)
WEB (61)
URL (48)
hardware (46)
javascript (36)
Linux (34)
blog (30)
C++ (16)
所有關鍵字
新增 URL
GDB 追蹤 memory corruption
by thinker
2 Columns
關鍵字:
coding
在不久之前,在 linkname:[GDB 自動化 debug] http://heaven.branda.to/~thinker/GinGin_CGI.py/show_id_doc/351 這篇文章中,簡單提到如何用 script 控制 gdb 。而今天又因為 MadButterfly 的$範例$程式裡的某個 bug ,再次使用相同的技巧。這次遇到的是一種典型的錯誤,某塊記憶體不知何時被修改,造成程式錯誤。 我將問題簡化一下。有一個變數 V,在程式一啟動之後就會 initialize 成特定值 k。但因未知原因,結果 V 不知何時被改成 m。為了要查出倒底是誰改了 V 的值,一般的做法是檢視程式流程,找出所有可能會改到 V 的地方。但有時侯根本是 pointer 亂指,不小心改到該變數。這時肉眼檢視的方法就不太可行了。這時,最重要的是找出程式是執行到什麼步驟時,該變數會被改變。 如果以一般的做法,就是到處 printf() ,然後不斷的 compile 、重新執行。這很沒有效率,因為無法動態檢視其它變數,以進行比較。比較有效的方法是,在該變數被修改時能自動讓 gdb 停下來。這時,在 gdb 設定 watchpoint 就可以達到這個目的。但,有些平台的 $hardware$ 並不支援 watchpoint ,這時 gdb 會以連續 single step 的方式執行,以達到 watchpoint 的效果。但這會非常非常的慢。如果程式複雜的話,這幾乎不可行。這時,透過適當的設定 break point ,更能快速的鎖定問題的發生點。 做法是,先把程式執行流程中,可疑的地點都設定 break point 如下 {{{#!raw break xxx.c:123 if V != k }}} 這時,這個 break 會在 xxx.c:123 的位置,檢查變數 V 是否為 k。若不為 k ,則程式會暫停執行,否則 break point 不會發生效果。這時,你可以到處設定 break point ,將問題鎖定在一個範圍,並不斷的縮小範圍,直到找到特定的位置。這方式的好處是你可以快速的設定,然後再重新執行。並且可檢視 process 的狀態,以決定新的 break point 要加在哪。 有時侯,你要監看的記憶體是動態配置的。因此,你必需在配置時才知道其位址。這時,可在配置該記憶體的指令設定 break point ,並記下配置的位址。 {{{#!raw break xxx.c:567 commands silent set $$addr=p continue end }}} 假定,在 xxx.c:567 的前一個指令,會將配置到的記憶體位址存在 local variable p。那麼上面的設定可以將該位址存在 gdb 的 convenience variable $$addr 裡。那麼我們就可以在其它 break point 裡檢查該位址的內容。例如 {{{#!raw break xxx.c:123 if *$$addr != k }}} 就能在程式執行到 xxx.c:123 位置時,檢查 $$addr 所指的記憶體位址內容。 這些設定,可以寫在一個文字檔,例如 foo.txt {{{#!raw break xxx.c:567 commands ....... end }}} 那麼我們就可以透過 gdb 參數,不斷重複這些設定 {{{#!raw gdb -x foo.txt your_progm }}}
最後更新時間: 2009-09-14 13:36:00 CST |
引用
查詢:
COMMENTS: