一個C++中的Heap Corrupt錯誤的分析
這兩天一直在研究一個Crash問題,其表現(xiàn)非常明顯就是Memory Heap被破壞了,但是由于破壞堆的現(xiàn)場無法準(zhǔn)確定位,發(fā)生Crash的地方已經(jīng)不是現(xiàn)場,所以一直都沒找到原因。最后只好將代碼Roll Back回去,一個一個模塊的試,最終發(fā)現(xiàn)問題出現(xiàn)在某一個模塊中指針類型的強(qiáng)制轉(zhuǎn)換引起的虛函數(shù)調(diào)用錯誤上。錯誤是這樣的,有一個指針是A類型的,被強(qiáng)制轉(zhuǎn)換為B類型,并且通過B類型調(diào)用B的虛函數(shù),但是實(shí)際上調(diào)用的虛函數(shù)地址在A的虛函數(shù)表中。由于兩者參數(shù)并不相同,所以導(dǎo)致錯誤出現(xiàn)。
B類型的函數(shù)參數(shù)中有一個std::vector類型,由于c++遵循cdecl調(diào)用約定,所以是由被調(diào)用端負(fù)責(zé)清理堆棧,這時候就會調(diào)用std::vector的析構(gòu)函數(shù),而實(shí)際上該參數(shù)已經(jīng)在調(diào)用A的虛函數(shù)時被破壞了,在執(zhí)行完這個函數(shù)之后,棧是正確的,但是堆已經(jīng)被std::vector的析構(gòu)函數(shù)破壞,所以出現(xiàn)了heap Corruption的錯誤。
Heap Corruption是C++開發(fā)中非常棘手的一個問題,其引起的Crash有兩點(diǎn)非常難以琢磨:
1. 在Debug版較難或者不出現(xiàn),在Release版常常出現(xiàn)
2. 在Release版本上也是在非現(xiàn)場出現(xiàn),而且往往在大量釋放內(nèi)存的地方出現(xiàn)。
相信應(yīng)該有比較好C++的Heap Corruption工具,BoundChecker曾經(jīng)用過,可惜太復(fù)雜不會用,不知道有沒有非常有效的檢測Heap Corruption工具。