锘??xml version="1.0" encoding="utf-8" standalone="yes"?> 1.1 MemWatch鐨勫唴瀛樺鐞?br> MemWatch灝嗘墍鏈夊垎閰嶇殑鍐呭瓨鐢?xFE濉厖錛屾墍浠ワ紝濡傛灉浣犵湅鍒伴敊璇殑鏁版嵁鏄敤0xFE濉厖鐨勶紝閭e氨鏄綘娌℃湁鍒濆鍖栨暟鎹備緥澶栨槸calloc()錛屽畠浼氱洿鎺ユ妸鍒嗛厤鐨勫唴瀛樼敤0濉厖銆?/p>
MemWatch灝嗘墍鏈夊凡閲婃斁鐨勫唴瀛樼敤0xFD濉厖(zapped with 0xFD).濡傛灉浣犲彂鐜頒綘浣跨敤鐨勬暟鎹槸鐢?xFD濉厖鐨勶紝閭d綘灝變嬌鐢ㄧ殑鏄凡閲婃斁鐨勫唴瀛樸傚湪榪欑鎯呭喌錛屾敞鎰廙emWatch浼氱珛鍗蟲妸涓涓?閲婃斁浜嗙殑鍧椾俊鎭?濉湪閲婃斁浜嗙殑鏁版嵁鍓嶃傝繖涓潡鍖呮嫭鍏充簬鍐呭瓨鍦ㄥ摢鍎塊噴鏀劇殑淇℃伅錛屼互鍙鐨勬枃鏈艦寮忓瓨鏀撅紝鏍煎紡涓?FBI<counter>filename(line)"銆傚:"FBI<267>test.c(12)".浣跨敤FBI浼氶檷浣巉ree()鐨勯熷害錛屾墍浠ラ粯璁ゆ槸鍏抽棴鐨勩備嬌鐢╩wFreeBufferInfo(1)寮鍚? 涓轟簡甯姪璺熻釜閲庢寚閽堢殑鍐欐儏鍐碉紝MemWatch鑳芥彁渚沶o-mans-land錛圢ML錛夊唴瀛樺~鍏呫俷o-mans-land灝嗕嬌鐢?xFC濉厖.褰搉o-mans-land寮鍚椂錛孧emWatch杞彉閲婃斁鐨勫唴瀛樹負NML濉厖鐘舵併?/p>
1.2鍒濆鍖栧拰緇撴潫澶勭悊 褰撶劧錛屽鏋滄病鏈夋墜鍔ㄨ皟鐢╩wInit()錛孧emWatch鑳借嚜鍔ㄥ垵濮嬪寲.濡傛灉鏄繖縐嶆儏褰紝memwatch浼氫嬌鐢╝text()娉ㄥ唽mwTerm()鐢ㄤ簬atexit-queue. 瀵逛簬浣跨敤鑷姩鍒濆鍖?a onclick="javascript:tagshow(event, '%BC%BC%CA%F5');" href="javascript:;" target=_self>鎶鏈?/font>鏈変竴涓憡璇?濡傛灉浣犳墜鍔ㄨ皟鐢╝texit()浠ヨ繘琛屾竻鐞?a onclick="javascript:tagshow(event, '%B9%A4%D7%F7');" href="javascript:;" target=_self>宸ヤ綔錛宮emwatch鍙兘鍦ㄤ綘鐨勭▼搴忕粨鏉熷墠灝辯粓姝€備負浜嗗畨鍏ㄨ搗瑙侊紝璇鋒樉寮忎嬌鐢╩wInit()鍜宮wTerm(). 娑夊強鐨勫嚱鏁頒富瑕佹湁錛?/p>
mwInit() mwTerm() mwAbort() 1.3 MemWatch鐨処/O 鎿嶄綔 濡傛灉浣犱笉鑳戒嬌鐢ㄦ棩蹇楋紝鎴栬呬笉鎯充嬌鐢紝涔熸病鏈夐棶棰樸傚彧瑕佷嬌鐢ㄧ被鍨嬩負"void func(int c)"鐨勫弬鏁拌皟鐢╩wSetOutFunc()錛岀劧鍚庢墍鏈夌殑杈撳嚭閮戒細鎸夊瓧鑺傚畾鍚戝埌璇ュ嚱鏁? 褰揂SSERT鎴栬匳ERIFY澶辮觸鏃訛紝MemWatch涔熸湁Abort/Retry/Ignore澶勭悊鏈哄埗銆傞粯璁ょ殑澶勭悊鏈哄埗娌℃湁I/O鎿嶄綔錛屼絾鏄細鑷姩涓柇紼嬪簭銆備綘鍙互浣跨敤浠諱綍鍏朵粬Abort/Retry/Ignore鐨勫鐞嗘満鍒?鍙浠ュ弬鏁?void func(int c)"璋冪敤mwSetAriFunc()銆傚悗闈㈠湪1.2浣跨敤涓鑺備細璇︾粏璁茶В銆?/p>
娑夊強鐨勫嚱鏁頒富瑕佹湁錛?/p>
mwTrace() mwPuts() mwSetOutFunc() mwSetAriFunc() mwSetAriAction() mwAriHandler() mwBreakOut() 1.4 MemWatch瀵笴++鐨勬敮鎸?br> 鍙互灝哅emWatch鐢ㄤ簬C++,浣嗘槸涓嶆帹鑽愯繖涔堝仛銆傝璇︾粏闃呰memwatch.h涓叧浜庡C++鐨勬敮鎸併?/p>
2 浣跨敤 浣跨敤GCC緙栬瘧錛堟敞鎰忥細涓嶆槸閾炬帴錛夎嚜宸辯殑紼嬪簭鏃訛紝鍔犲叆-DMEMWATCH -DMW_STDIO 2.2 浣跨敤MemWatch鎻愪緵鐨勫姛鑳?br>1錛夊湪紼嬪簭涓父鐢ㄧ殑MemWatch鍔熻兘鏈夛細 mwTRACE ( const char* format_string, ... ); mwASSERT ( int, const char*, const char*, int ) mwVERIFY ( int, const char*, const char*, int ) mwPuts ( const char* text ) ARI鏈哄埗錛?mwSetAriFunc(int (*func)(const char *))錛?br> mwSetAriAction(int action)錛?br> mwAriHandler ( const char* cause )錛?/p>
mwSetOutFunc (void (*func)(int)) mwIsReadAddr(const void *p, unsigned len ) mwIsSafeAddr(void *p, unsigned len ) mwStatistics ( int level ) mwBreakOut ( const char* cause) 2錛塵wTRACE錛宮wASSERT錛宮wVERIFY鍜宮wPuts欏懼悕鎬濅箟錛屽氨涓嶅啀璧樿堪銆備粎闇瑕佹敞鎰忕殑鏄紝Memwatch瀹氫箟浜嗗畯TRACE, ASSERT 鍜?VERIFY.濡傛灉浣犲凡浣跨敤鍚屽悕鐨勫畯,memwatch2.61鍙婃洿楂樼増鏈殑memwatch涓嶄細瑕嗙洊浣犵殑瀹氫箟銆侻emWatch2.61鍙婁互鍚庯紝瀹氫箟浜唌wTRACE, mwASSERT 鍜?mwVERIFY瀹忥紝榪欐牱錛屼綘灝辮兘紜畾浣跨敤鐨勬槸memwatch鐨勫畯瀹氫箟銆?.61鐗堟湰鍓嶇殑memwatch浼氳鐩栧凡瀛樺湪鐨勫悓鍚嶇殑TRACE, ASSERT 鍜?VERIFY瀹氫箟銆?/p>
褰撶劧錛屽鏋滀綘涓嶆兂浣跨敤MemWatch鐨勮繖鍑犱釜瀹忓畾涔夛紝鍙互瀹氫箟MW_NOTRACE, MW_NOASSERT 鍜?MW_NOVERIFY瀹忥紝榪欐牱MemWatch鐨勫畯瀹氫箟灝變笉璧蜂綔鐢ㄤ簡銆傛墍鏈夌増鏈殑memwatch閮介伒鐓ц繖涓鍒欍?/p>
3錛堿RI鏈哄埗鍗崇▼搴忚緗殑“Abort, Retry, Ignore閫夋嫨闄烽槺銆?/p>
mwSetAriFunc錛?/p>
璁劇疆“Abort, Retry, Ignore”鍙戠敓鏃剁殑MemWatch璋冪敤鐨勫嚱鏁?褰撹繖鏍瘋緗皟鐢ㄧ殑鍑芥暟鍦板潃鏃訛紝瀹為檯鐨勯敊璇秷鎭笉浼氭墦鍗板嚭鏉ワ紝浣嗕細浣滀負涓涓弬鏁拌繘琛屼紶閫掋?/p>
濡傛灉鍙傛暟浼犻扤ULL錛孉RI澶勭悊鍑芥暟浼氳鍐嶆鍏抽棴銆傚綋ARI澶勭悊鍑芥暟鍏抽棴鍚庯紝 meewatch浼氳嚜鍔ㄨ皟鐢ㄦ湁mwSetAriAction()鎸囧畾鐨勬搷浣溿?/p>
姝e父鎯呭喌涓嬶紝澶辮觸鐨凙SSERT() or VERIFY()浼氫腑鏂綘鐨勭▼搴忋備絾榪欏彲浠ラ氳繃mwSetAriFunc()鏀瑰彉錛屽嵆閫氳繃灝嗗嚱鏁?int myAriFunc(const char *)"浼犵粰瀹冨疄鐜般備綘鐨勭▼搴忓繀欏昏闂敤鎴鋒槸鍚︿腑鏂紝閲嶈瘯鎴栬呭拷鐣ヨ繖涓櫡闃便傝繑鍥?鐢ㄤ簬Abort錛?1鐢ㄤ簬Retry錛屾垨鑰?瀵逛簬Ignore銆傛敞鎰弐etry鏃訛紝浼氬鑷磋〃杈懼紡閲嶆柊姹傚? MemWatch鏈変釜榛樿鐨凙RI澶勭悊鍣ㄣ傞粯璁ゆ槸鍏抽棴鐨勶紝浣嗕綘鑳介氳繃璋冪敤mwDefaultAri()寮鍚傛敞鎰忚繖浠嶇劧浼氫腑姝綘鐨勭▼搴忛櫎闈炰綘瀹氫箟MEMWATCH_STDIO鍏佽MemWatch浣跨敤鏍囧噯C鐨処/O嫻併?/p>
鍚屾椂錛岃緗瓵RI鍑芥暟涔熶細瀵艱嚧MemWatch涓嶅皢ARI鐨勯敊璇俊鎭啓鍚戞爣鍑嗛敊璇緭鍑猴紝閿欒瀛楃涓茶屾槸浣滀負'const char *'鍙傛暟浼犻掑埌ARI鍑芥暟. mwSetAriAction錛?/p>
濡傛灉娌℃湁ARI澶勭悊鍣ㄨ鎸囧畾錛岃緗粯璁ょ殑ARI榪斿洖鍊箋傞粯璁ゆ槸MW_ARI_ABORT mwAriHandler錛?/p>
榪欐槸涓爣鍑嗙殑ARI澶勭悊鍣紝濡傛灉浣犲枩嬈㈠氨灝界鐢ㄣ傚畠灝嗛敊璇緭鍑哄埌鏍囧噯閿欒杈撳嚭錛屽茍浠庢爣鍑嗚緭鍏ヨ幏寰楄緭鍏ャ?/p>
mwSetOutFunc錛?/p>
灝嗚緭鍑鴻漿鍚戣皟鐢ㄨ呯粰鍑虹殑鍑芥暟(鍙傛暟鍗沖嚱鏁板湴鍧)銆傚弬鏁頒負NULL錛岃〃紺烘妸杈撳嚭鍐欏叆鏃ュ織鏂囦歡memwatch.log. mwIsReadAddr: 媯鏌ュ唴瀛樻槸鍚︽湁璇誨彇鐨勬潈闄?/p>
mwIsSafeAddr: 媯鏌ュ唴瀛樻槸鍚︽湁璇匯佸啓鐨勬潈闄?/p>
mwStatistics: 璁劇疆鐘舵佹悳闆嗗櫒鐨勮涓恒傚搴旂殑鍙傛暟閲囩敤瀹忓畾涔夈?/p>
#define MW_STAT_GLOBAL 0 /* 浠呮悳闆嗗叏灞鐘舵佷俊鎭?*/ #define MW_STAT_MODULE 1 /* 鎼滈泦妯″潡綰х殑鐘舵佷俊鎭?*/ #define MW_STAT_LINE 2 /* 鎼滈泦浠g爜琛岀駭鐨勭姸鎬佷俊鎭?*/ #define MW_STAT_DEFAULT 0 /* 榛樿鐘舵佽緗?*/ mwBreakOut: 褰撴煇浜涙儏鍐礛emWatch瑙夊緱涓柇(break into)緙栬瘧鍣ㄦ洿濂芥椂錛屽氨璋冪敤榪欎釜鍑芥暟.濡傛灉浣犲枩嬈嬌鐢∕emWatch,閭d箞鍙互鍦ㄨ繖涓嚱鏁頒笂璁劇疆鎵ц鏂偣銆?/p>
鍏朵粬鍔熻兘鐨勪嬌鐢紝璇峰弬鑰冩簮浠g爜鐨勮鏄庛?/p>
2.3鍒嗘瀽鏃ュ織鏂囦歡 嫻嬭瘯鏃ユ湡 鐘舵佹悳闆嗗櫒鐨勪俊鎭?/p>
浣跨敤MemWatch鐨勮緭鍑哄嚱鏁版垨瀹忥紙濡俆RACE絳夛級鐨勪俊鎭?/p>
MemWatch鎹曡幏鐨勯敊璇俊鎭?/p>
鍐呭瓨浣跨敤鐨勫叏灞淇℃伅緇熻錛屽寘鎷洓鐐癸細1錛夊垎閰嶄簡澶氬皯嬈″唴瀛?2錛夋渶澶у唴瀛樹嬌鐢ㄩ噺3錛夊垎閰嶇殑鍐呭瓨鎬婚噺 4錛変負閲婃斁鐨勫唴瀛樻繪暟 MemWatch鎹曡幏鐨勯敊璇褰曞湪鏃ュ織鏂囦歡涓殑杈撳嚭鏍煎紡濡備笅錛?/p>
message: <sequence-number> filename(linenumber), information 2.4 娉ㄦ剰浜嬮」 mwTerm()鐢ㄤ簬緇堟MemWatch. 濡傛灉鍦ㄦ祦紼嬩腑鎹曡幏浜嗙▼搴忕殑寮傚父涓柇錛岄偅涔堥渶瑕佽皟鐢╩wAbort()鑰屼笉鏄?/p>
mwTerm()銆傚嵆浣挎湁鏄劇ず鐨勮皟鐢╩wTerm()錛宮wAbort()涔熷皢緇堟MemWatch銆?/p>
MemWatch涓嶈兘紜繚鏄嚎紼嬪畨鍏ㄧ殑銆傚鏋滀綘紕板閥浣跨敤Wind32鎴栬呬綘浣跨敤浜嗙嚎紼嬶紝浣滀負2.66錛屾槸鍒濇鏀寔綰跨▼鐨勩傚畾涔塛IN32鎴栬匨W_PTHREADS浠ユ槑紜敮鎸佺嚎紼嬨傝繖浼氬鑷翠竴涓叏灞浜掓枼鍙橀噺浜х敓錛屽悓鏃跺綋璁塊棶鍏ㄥ眬鍐呭瓨閾炬椂錛孧emWatch浼氶攣瀹氫簰鏂ュ彉閲忥紝浣嗚繖榪滀笉鑳借瘉鏄庢槸綰跨▼瀹夊叏鐨勩?/p>
3 緇撹 瀹冪殑瀹樻柟緗戝潃鏄?http://www.valgrind.org/ 涓嬭澆鏈鏂扮増鏈殑Valgrind錛岀洰鍓嶆槸3.2.0銆?wget http://www.valgrind.org/downloads/valkyrie-1.2.0.tar.bz2 鎵ц甯歌鐨勫畨瑁呮楠わ細./confgure && make && make install銆傛敞鎰忥細 緋葷粺蹇呴』瀹夎QT鐨勫紑鍙戝寘銆傚嵆渚胯繖鏍峰湪make 鏃惰繕鏄嚭鐜皅platformdefs.h榪欎釜鏂囦歡鎵句笉鍒扮殑鎯呭喌錛屽鑷磎ake澶辮觸銆傛煡鎵劇郴緇熶腑鐨剄platformdefs.h 涔嬪悗錛屽彂鐜版病鏈夊瓨鍦ㄤ簬qt鐨勬爣鍑嗗ご鏂囦歡鐩綍/usr/lib/qt-3.3/include銆傚鏄皢/usr/lib/qt-3.3/mkspecs/linux-g++/ 鐩綍涓嬭澶存枃浠跺鍒舵爣鍑嗗ご鏂囦歡鐩綍錛岄噸鏂癿ake 錛屽悗闈竴鍒嘜K銆?/p>
MemWatch鐢?Johan Lindh 緙栧啓錛屾槸涓涓紑鏀炬簮浠g爜 C 璇█鍐呭瓨閿欒媯嫻嬪伐鍏楓侻emWatch鏀寔 ANSI C錛屽畠鎻愪緵緇撴灉鏃ュ織綰綍錛岃兘媯嫻嬪弻閲嶉噴鏀撅紙double-free錛夈侀敊璇噴鏀撅紙erroneous free錛夈佸唴瀛樻硠婕忥紙unfreed memory錛夈佹孩鍑?Overflow)銆佷笅婧?Underflow)絳夌瓑銆?/p>
涓鑸潵璇達紝鍦ㄧ▼搴忎腑浣跨敤MemWatch鐨勫姛鑳斤紝闇瑕佹墜鍔ㄦ坊鍔爉wInit()榪涜鍒濆鍖栵紝騫剁敤瀵瑰簲鐨刴wTerm ()榪涜緇撴潫澶勭悊銆?/p>
瀵逛簬涓鑸殑鎿嶄綔錛孧emWatch鍒涘緩memwatch.log鏂囦歡銆傛湁鏃訛紝璇ユ枃浠朵笉鑳借鍒涘緩;MemWatch浼氳瘯鍥懼垱寤簃emwatNN.log鏂囦歡錛孨N鍦?1~99涔嬮棿銆?/p>
2.1 涓鴻嚜宸辯殑紼嬪簭鎻愪緵MemWatch鍔熻兘
鍦ㄨ浣跨敤MemWatch鐨?c鏂囦歡涓寘鍚ご鏂囦歡"memwatch.h"
濡傦細gcc -DMEMWATCH -DMW_STDIO –o test.o –c test1.c
鎴朤RACE ( const char* format_string, ... );
鎴朅SSERT ( int, const char*, const char*, int )
鎴朧ERIFY ( int, const char*, const char*, int )
鏃ュ織鏂囦歡memwatch.log涓寘鍚殑淇℃伅涓昏鏈変互涓嬪嚑鐐癸細
mwInit()鍜宮wTerm()鏄搴旂殑.鎵浠ヤ嬌鐢ㄤ簡澶氬皯嬈wInit()錛屽氨闇瑕佽皟鐢ㄥ灝戞
浠嶮emWatch鐨勪嬌鐢ㄥ彲浠ュ緱鐭ワ紝鏃犳硶鐢ㄤ簬鍐呮牳妯″潡銆傚洜涓篗emWatch鑷韓灝變嬌鐢ㄤ簡搴旂敤灞傜殑鎺ュ彛錛岃屼笉鏄唴鏍告帴鍙c備絾鏄紝瀵逛簬鏅氱殑搴旂敤灞傜▼搴忥紝鎴戣涓鴻繕鏄瘮杈冩湁鐢紝騫朵笖鏄紑婧愮殑錛屽彲浠ヨ嚜宸變慨鏀逛唬鐮佸疄鐜幫紱瀹冭兘鏂逛究鍦版煡鎵懼唴瀛樻硠婕忥紝鐗瑰埆鏄彁渚涚殑鎺ュ彛鍑芥暟綆鍗曟槗鎳傦紝瀛︿範鎺屾彙寰堝鏄擄紝瀵瑰簲鐢ㄥ眰紼嬪簭鐨?a onclick="javascript:tagshow(event, '%B5%A5%D4%AA%B2%E2%CA%D4');" href="javascript:;" target=_self>鍗曞厓嫻嬭瘯浼氳緝閫傜敤銆?/p>
鍒濇浣跨敤
緙栬瘧濡備笅浠g爜: gcc -Wall example.c -g -o example
#include <stdlib.h>
void f(void)
{
int* x = malloc(10 * sizeof(int));
x[10] = 0; // problem 1: heap block overrun
} // problem 2: memory leak -- x not freed
int main(void)
{
f();
return 0;
}
娉ㄦ剰錛歡cc 鐨?g 閫夐」璁¬algrind璋冭瘯杈撳嚭鏃舵寚鍑虹浉搴斾俊鎭殑浠g爜鎵鍦ㄧ殑琛屽彿銆?/p>
valgrind --tool=memcheck --leak-check=yes ./example |
==6742== Memcheck, a memory error detector for x86-linux. ==6742== Copyright (C) 2002-2004, and GNU GPL'd, by Julian Seward et al. ==6742== Using valgrind-2.2.0, a program supervision framework for x86-linux. ==6742== Copyright (C) 2000-2004, and GNU GPL'd, by Julian Seward et al. ==6742== For more details, rerun with: -v ==6742== ==6742== Invalid write of size 4 ==6742== at 0x8048384: f (example.c:6) ==6742== by 0x80483AC: main (example.c:12) ==6742== Address 0x1B908050 is 0 bytes after a block of size 40 alloc'd ==6742== at 0x1B904984: malloc (vg_replace_malloc.c:131) ==6742== by 0x8048377: f (example.c:5) ==6742== by 0x80483AC: main (example.c:12) ==6742== ==6742== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 12 from 1) ==6742== malloc/free: in use at exit: 40 bytes in 1 blocks. ==6742== malloc/free: 1 allocs, 0 frees, 40 bytes allocated. ==6742== For counts of detected errors, rerun with: -v ==6742== searching for pointers to 1 not-freed blocks. ==6742== checked 1360800 bytes. ==6742== ==6742== ==6742== 40 bytes in 1 blocks are definitely lost in loss record 1 of 1 ==6742== at 0x1B904984: malloc (vg_replace_malloc.c:131) ==6742== by 0x8048377: f (example.c:5) ==6742== by 0x80483AC: main (example.c:12) ==6742== ==6742== LEAK SUMMARY: ==6742== definitely lost: 40 bytes in 1 blocks. ==6742== possibly lost: 0 bytes in 0 blocks. ==6742== still reachable: 0 bytes in 0 blocks. ==6742== suppressed: 0 bytes in 0 blocks. ==6742== Reachable blocks (those to which a pointer was found) are not shown. ==6742== To see them, rerun with: --show-reachable=yes |
涓婇潰鐨凜紼嬪簭瀛樺湪涓や釜閿欒錛?. 鏁扮粍涓嬫爣瓚婄晫錛?. 鍒嗛厤鐨勫唴瀛樻病鏈夐噴鏀撅紝瀛樺湪鍐呭瓨娉勯湶鐨勯棶棰樸傚浜庨敊璇?錛岀湅Valgrind鐨勮皟璇曚俊鎭墖鏂?
==6742== Invalid write of size 4 ==6742== at 0x8048384: f (example.c:6) ==6742== by 0x80483AC: main (example.c:12) ==6742== Address 0x1B908050 is 0 bytes after a block of size 40 alloc'd ==6742== at 0x1B904984: malloc (vg_replace_malloc.c:131) ==6742== by 0x8048377: f (example.c:5) |
瀵逛簬閿欒2錛岀湅榪欎釜
==6742== malloc/free: 1 allocs, 0 frees, 40 bytes allocated. ...... ==6742== 40 bytes in 1 blocks are definitely lost in loss record 1 of 1 |