原 使用Gflags來檢測heap問題

2021-06-16 04:37:19 字數 3373 閱讀 4769

gflags是windows debug tools 工具包下的乙個工具,在windows 2000的resource kit中也可以找得到。用來設定一些除錯屬性,總體上分為3個級別system,kernel和image file。我們設定好path環境變數,將其指向debug tools工具的目錄下。

gflags 

- 老牌的pageheap配置工具,有命令列和gui兩種操作方式,功能比較全,包含在windbg偵錯程式安裝包內。同樣在windows 2000 professional sp2 以上可用。

一些使用gflags命令列的例子:

配置正常頁堆:

"c:/program files/debugging tools for windows (x86)/gflags.exe" /p /enable qq.exe

配置完全頁堆:

"c:/program files/debugging tools for windows (x86)/gflags.exe" /p /enable qq.exe /full

列出當前啟動了頁堆的程序列表:

"c:/program files/debugging tools for windows (x86)/gflags.exe" /p

取消頁堆設定:

"c:/program files/debugging tools for windows (x86)/gflags.exe" /p /disable qq.exe

一些特殊選項解釋:

/unaligned

這個選項只能用於完全頁堆。當我們從普通堆管理器分配一塊記憶體時,記憶體總是8位元組對齊的,頁堆預設情況下也會使用這個對齊規則,但是這會導致分配的記憶體塊的結尾不能跟頁邊界精確對齊,可能存在0-7個位元組的間隙,顯然,對位於間隙範圍內的訪問是不會被立即發現。更準確的說,讀操作將永遠不能被發現,寫操作則要等到記憶體塊釋放時校驗間隙空間內的填充資訊時才發現。/unaligned用於修正這個缺陷,它指定頁堆管理器不必遵守8位元組對齊規則,保證記憶體塊尾部精確對齊頁邊界。

需要注意的是,一些程式啟用這個選項可能出現異常,例如ie和qq就不支援。

/backwards

這個選項只能用於完全頁堆。這個選項使得分配的記憶體塊頭部與頁邊界對齊(而不是尾部與邊界對齊),通過這個選項來檢查頭部的訪問越界。

/debug

指定一啟動程序即attach到偵錯程式,對於那些不能自動生成dump的程式,是比較有用的選項。

完全頁堆:

當分配一塊記憶體時,通過調整記憶體塊的分配位置,使其結尾恰好與系統分頁邊界對齊,然後在邊界處再多分配乙個不可訪問的頁作為保護區域。這樣,一旦出現記憶體讀/寫越界時,程序就會crash,從而幫助及時檢查記憶體越界。

因為每次分配的記憶體都要以這種形式布局,尤其對於小片的記憶體分配,即使分配乙個位元組,也要分配乙個記憶體頁,和乙個保留的虛擬記憶體頁(注意在目前的實現中,這個用作邊界保護區域的頁從來不會被提交)。這就需要大量的記憶體,到底乙個程序需要多少記憶體,很難估算,因此在使用page heap前,至少保證你的機器至少設定了1g虛擬記憶體以上。

正常頁堆

正常頁堆原理與crt除錯記憶體分配函式類似,通過分配少量的填充資訊,在釋放記憶體塊時檢查填充區域。來檢測記憶體是否被損壞,此方法的優點是極大的減少了記憶體耗用量。缺點是只能在釋放塊時檢測,不太好跟蹤出錯的**位置。

頁堆能處理的錯誤型別:

錯誤型別 

正常頁堆              

整頁堆 

堆控制代碼無效 

立即發現 

立即發現 

堆記憶體塊指標無效 

立即發現 

立即發現 

多執行緒訪問堆不同步 

立即發現 

立即發現 

假設重新分配返回相同位址(realloc) 

90% 記憶體釋放後發現 

90% 立即發現 

記憶體塊重複釋放 

90% 立即發現 

90% 立即發現 

訪問已釋放的記憶體塊 

90% 在實際釋放後發現 

90% 立即發現 

訪問塊結尾之後的內容 

在釋放後發現 

立即發現 

訪問塊開始之前的內容 

在釋放後發現 

立即發現 

以下是舉例:

前期工作: 將gflags(預設安裝在c:/program files/debugging tools for windows (x86))加入到path

案例1:

int _tmain(int argc, _tchar* argv)

程式本身是有問題的。陣列已經越界,但是debug模式下並不報錯,release模式下也很大可能是不crash的。

在命令提示符下執行:

>gflags /p /enable test.exe /full

在release模式執行test.exe。exception將直接定位到 p[8] = 10; 這一行

案例2:

int _tmain(int argc, _tchar* argv)

以上**和案例1僅有一點不同,就是陣列大小。但是如果執行

gflags /p /enable test.exe /full

在release模式下並不會出現exception並定位到 p[9] = 10;

原因是沒有設定/unaligned引數,具體看說明。案例2中,陣列有9位元組大小,按記憶體8位元組對齊的說法,這塊記憶體應該是

16位元組,後面還有7位元組的空間,所以 p[9] = 10; 並不會產生exception。設定 /unaligned 引數,禁止8位元組對齊,就

可以跟蹤到 p[9] = 10; 這個exception

>gflags /p /enable test.exe /full /unaligned

案例3:

class a

};int _tmain(int argc, _tchar* argv)

在debug模式下可能產生exception:

heap:   free   heap   block   ******xx modified   at   ******xx  after   it   was   freed

在release模式下執行並不報錯,但是程式本身是有問題的,delete this; 之後,又給成員變數 a=10;

這顯然是不對的。

>gflags /p /enable test.exe /full

此時在debug下執行程式,會產生exception,並定位到   a = 10;

使用gflags來檢測heap問題

gflags是windows debug tools 工具包下的乙個工具,在windows 2000的resource kit中也可以找得到。用來設定一些除錯屬性,總體上分為3個級別system,kernel和image file。我們設定好path環境變數,將其指向debug tools工具的目錄...

使用sobel檢測器來提取邊緣

使用sobel檢測器來提取邊緣 f imread building.tif 讀取影象 subplot 3,2,1 imshow f title 原影象 gt,t edge f,sobel vertical 用sobel來提取垂直邊緣檢測 subplot 3,2,2 imshow gt title 垂...

使用AI來檢測違反社交距離的行為

作者 priya dwivedi 編譯 flin medium 美國和歐洲的許多城市現在都在謹慎地重新開放。人們被要求在外出時保持安全距離。但是人們照著做嗎?城市對人們的安全距離是否符合規則進行評估並採取相應的行動是很重要的。如果大多數人都遵守疫情期間的命令,那麼就可以安全地開放更多的公共場合。然而...