VC 快速偵測斷言錯誤導致的記憶體洩露

2021-06-07 07:23:28 字數 2924 閱讀 1079

vc:快速偵測斷言錯誤導致的記憶體洩露  

2010-09-18 21:40:16|  分類: 疑難雜症 |字型大小 訂閱

程式在退出時,由於斷言錯誤,導致記憶體大量洩露。之前曾經遇到過類似的情況,當時是一步一步地除錯,最後解決。這次再次遇到,而且情況更加複雜,所以,我想出了乙個快速偵測的方法。

替換系統預設的斷言語句:(加在stdafx.h檔案的前面,或者是第乙個編譯的檔案裡面,以便能夠替換所有的斷言)

#undef atlassert

#define atlassert(x) \

g_tracenotime("%s(%d):%s \n", __file__, __line__, __function__);\

_asserte((x));

這裡使用atlassert。因為我使用的是vc 2008,2008中,mfc的assert是採用的atlassert的,而atl也是atlassert的,同時,console控制台程式也可以方便地使用atlassert。

g_tracenotime的實現:

void g_tracenotime(const char* pszformat, ...); //列印除錯資訊

void g_tracenotime(const wchar_t* pszformat, ...); //列印除錯資訊

#define packet_buffer_max_size (64*1024)

void g_tracenotime(const char* pszformat, ...)

;va_list arglist;

systemtime t;

getlocaltime(&t);

va_start(arglist, pszformat);

vsprintf_s(buf+strlen(buf), sizeof(buf)-strlen(buf), pszformat, arglist);

strcat_s(buf, sizeof(buf), "\r\n");

va_end(arglist);

outputdebugstringa(buf);

}void g_tracenotime(const wchar_t* pszformat, ...)

;va_list arglist;

systemtime t;

getlocaltime(&t);

va_start(arglist, pszformat);

vswprintf_s(buf+wcslen(buf), sizeof(buf)/sizeof(wchar_t)-wcslen(buf), pszformat, arglist);

wcscat_s(buf, sizeof(buf)/sizeof(wchar_t), l"\r\n");

va_end(arglist);

outputdebugstringw(buf);

}這樣雖然可以,但是還是不能看到斷言的內容,於是改為:

#undef atlassert

#define atlassert(x) \

g_tracenotime("%s(%d):%s "#x"\n", __file__, __line__, __function__);\

_asserte((x));

對unicode的支援:#undef atlassert

#define atlassert(x) \

g_tracenotime("%s(%d):%s "#x"\n", __filew__, __line__, __functionw__);\

_asserte((x));

暫時就這樣。執行一下,看看結果。最後乙個trace列印的結果:

****.cpp(1072):****::createbitmapex (ecompression == bi_rgb) || (ecompression == bi_bitfields)

是我自己寫的乙個函式裡面的斷言!

基本上知道問題出哪兒了,但是,如果改了這一處斷言,其他地方還是會出問題!因為這些斷言發生時,程式正在退出,系統資源正在釋放!所以,在發現程式退出時,就不能再執行這些斷言語句!——只要正確地**某些資源,就可以保證程式不會在退出時執行到這裡,這樣就可以解決問題。

於是:#undef atlassert

#define atlassert(x) \

g_tracenotime("%s(%d):%s, "#x"\n", __file__, __line__, __function__);\

try\

\catch (...)\

\//斷點函式

int g_break();

int g_break()

這樣的**,執行的效果應該很好!當斷言導致程序崩潰時,異常**獲到g_break();,所以,我只要在g_break()裡面下乙個斷點,然後就等著斷言崩潰就行了!

然而,這只是我的一廂情願。程式並不能執行到這裡,這個斷言崩潰很嚴重,直接是程序崩潰,異常都捕獲不到!

沒有關係,檢視trace資訊。

*****.cpp(57):****::close, close socket! m_is_closed_notify=1

在斷言崩潰前面,最後乙個正常的trace除錯資訊是這句,那麼,就在這裡下斷點!

即:先在這句下斷點,中斷發生後,再在g_break()裡面下斷點。

#undef atlassert

#define atlassert(x) \

g_tracenotime("%s(%d):%s, "#x, __file__, __line__, __function__);\

g_break();\

_asserte((x));\

經過數個小時的跟蹤,最後找到問題所在。將下面的**

void c****dlg::oncancel()

改為:void c****dlg::oncancel()

by:zhanyonhu

python 版本錯誤導致的 roscore 問題

cd usr bin sudo rm usr bin python 刪除原有的python連線檔案 sudo ln s usr bin python3.5 python 建立指向python3.x的連線 cd usr bin sudo rm usr bin python 刪除原有的python連線檔...

c 動態鏈結庫錯誤導致的程式執行異常

昨天改程式,明明 都編譯通過了,但是執行程式時老是出錯,一會兒說檔案載入異常,一會兒說找不到符號 symbol lookup error 在程式中加注釋也沒有列印,一度懷疑是見鬼了。後來搜了一下,一般報的找不到符號錯誤是因為鏈結錯誤造成了,就使用ldd命令檢視程式鏈結了什麼動態鏈結庫。結果發現編譯時...

硬碟分割槽表錯誤導致的問題和解決過程

兩個月前裝了win10預覽版 雙系統 嘗鮮,可能由於解除安裝方式不正確或者不完全,導致我的筆記本 win8.1 64bit 出現了乙個很費解的問題 在斷網的情況下則完全沒什麼,而一旦聯網 插上網線或者連wifi 之後就崩潰了,表現為資源管理器不間斷關閉重啟,而且無法開啟任何應用程式,不斷報錯 記憶體...