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 之後就崩潰了,表現為資源管理器不間斷關閉重啟,而且無法開啟任何應用程式,不斷報錯 記憶體...