青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

<2008年12月>
30123456
78910111213
14151617181920
21222324252627
28293031123
45678910

統(tǒng)計(jì)

  • 隨筆 - 44
  • 文章 - 0
  • 評(píng)論 - 86
  • 引用 - 0

常用鏈接

留言簿(6)

隨筆分類(31)

隨筆檔案(44)

Mining

最新隨筆

搜索

  •  

最新評(píng)論

閱讀排行榜

評(píng)論排行榜

用BoundsChecker檢測(cè)內(nèi)存泄漏 (zz)
  BoundsChecker采用一種被稱為 Code Injection的技術(shù),來截獲對(duì)分配內(nèi)存和釋放內(nèi)存的函數(shù)的調(diào)用。簡單地說,當(dāng)你的程序開始運(yùn)行時(shí),BoundsChecker的DLL被自動(dòng)載入進(jìn)程的地址空間(這可以通過system-level的Hook實(shí)現(xiàn)),然后它會(huì)修改進(jìn)程中對(duì)內(nèi)存分配和釋放的函數(shù)調(diào)用,讓這些調(diào)用首先轉(zhuǎn)入它的代碼,然后再執(zhí)行原來的代碼。BoundsChecker在做這些動(dòng)作的時(shí),無須修改被調(diào)試程序的源代碼或工程配置文件,這使得使用它非常的簡便、直接。

  這里我們以malloc函數(shù)為例,截獲其他的函數(shù)方法與此類似。

  需要被截獲的函數(shù)可能在DLL中,也可能在程序的代碼里。比如,如果靜態(tài)連結(jié)C-Runtime Library,那么malloc函數(shù)的代碼會(huì)被連結(jié)到程序里。為了截獲住對(duì)這類函數(shù)的調(diào)用,BoundsChecker會(huì)動(dòng)態(tài)修改這些函數(shù)的指令。

  以下兩段匯編代碼,一段沒有BoundsChecker介入,另一段則有BoundsChecker的介入:
126:?_CRTIMP?void?*?__cdecl?malloc?(
127:?size_t?nSize
128:?)
129:?{

00403C10?push?ebp
00403C11?mov?ebp,esp
130:?return?_nh_malloc_dbg(nSize,?_newmode,?_NORMAL_BLOCK,?NULL,?0);
00403C13?push?
0
00403C15?push?
0
00403C17?push?
1
00403C19?mov?eax,[__newmode?(0042376c)]
00403C1E?push?eax
00403C1F?mov?ecx,dword?ptr?[nSize]
00403C22?push?ecx
00403C23?call?_nh_malloc_dbg?(00403c80)
00403C28?add?esp,14h
131:?}
以下這一段代碼有BoundsChecker介入:
126:?_CRTIMP?void?*?__cdecl?malloc?(
127:?size_t?nSize
128:?)
129:?{

00403C10?jmp?01F41EC8
00403C15?push?
0
00403C17?push?
1
00403C19?mov?eax,[__newmode?(0042376c)]
00403C1E?push?eax
00403C1F?mov?ecx,dword?ptr?[nSize]
00403C22?push?ecx
00403C23?call?_nh_malloc_dbg?(00403c80)
00403C28?add?esp,14h
131:?}

  當(dāng)BoundsChecker介入后,函數(shù)malloc的前三條匯編指令被替換成一條jmp指令,原來的三條指令被搬到地址01F41EC8處了。當(dāng)程序進(jìn)入malloc后先jmp到01F41EC8,執(zhí)行原來的三條指令,然后就是BoundsChecker的天下了。大致上它會(huì)先記錄函數(shù)的返回地址(函數(shù)的返回地址在stack上,所以很容易修改),然后把返回地址指向?qū)儆贐oundsChecker的代碼,接著跳到malloc函數(shù)原來的指令,也就是在00403c15的地方。當(dāng)malloc函數(shù)結(jié)束的時(shí)候,由于返回地址被修改,它會(huì)返回到BoundsChecker的代碼中,此時(shí)BoundsChecker會(huì)記錄由malloc分配的內(nèi)存的指針,然后再跳轉(zhuǎn)到到原來的返回地址去。

  如果內(nèi)存分配/釋放函數(shù)在DLL中,BoundsChecker則采用另一種方法來截獲對(duì)這些函數(shù)的調(diào)用。BoundsChecker通過修改程序的DLL Import Table讓table中的函數(shù)地址指向自己的地址,以達(dá)到截獲的目的。

  截獲住這些分配和釋放函數(shù),BoundsChecker就能記錄被分配的內(nèi)存或資源的生命周期。接下來的問題是如何與源代碼相關(guān),也就是說當(dāng)BoundsChecker檢測(cè)到內(nèi)存泄漏,它如何報(bào)告這塊內(nèi)存塊是哪段代碼分配的。答案是調(diào)試信息(Debug Information)。當(dāng)我們編譯一個(gè)Debug版的程序時(shí),編譯器會(huì)把源代碼和二進(jìn)制代碼之間的對(duì)應(yīng)關(guān)系記錄下來,放到一個(gè)單獨(dú)的文件里(.pdb)或者直接連結(jié)進(jìn)目標(biāo)程序,通過直接讀取調(diào)試信息就能得到分配某塊內(nèi)存的源代碼在哪個(gè)文件,哪一行上。使用Code Injection和Debug Information,使BoundsChecker不但能記錄呼叫分配函數(shù)的源代碼的位置,而且還能記錄分配時(shí)的Call Stack,以及Call Stack上的函數(shù)的源代碼位置。這在使用像MFC這樣的類庫時(shí)非常有用,以下我用一個(gè)例子來說明:

void?ShowXItemMenu()
{
 …
 CMenu?menu;

 menu.CreatePopupMenu();
 
//add?menu?items.
 menu.TrackPropupMenu();
 …
}

void?ShowYItemMenu(?)
{
 …
 CMenu?menu;
 menu.CreatePopupMenu();
 
//add?menu?items.
 menu.TrackPropupMenu();
 menu.Detach();
//this?will?cause?HMENU?leak
 …
}

BOOL?CMenu::CreatePopupMenu()
{
 …
 hMenu?
=?CreatePopupMenu();
 …
}
當(dāng)調(diào)用ShowYItemMenu()時(shí),我們故意造成HMENU的泄漏。但是,對(duì)于BoundsChecker來說被泄漏的HMENU是在class CMenu::CreatePopupMenu()中分配的。假設(shè)的你的程序有許多地方使用了CMenu的CreatePopupMenu()函數(shù),如CMenu::CreatePopupMenu()造成的,你依然無法確認(rèn)問題的根結(jié)到底在哪里,在ShowXItemMenu()中還是在ShowYItemMenu()中,或者還有其它的地方也使用了CreatePopupMenu()?有了Call Stack的信息,問題就容易了。BoundsChecker會(huì)如下報(bào)告泄漏的HMENU的信息:
Function
File
Line

CMenu::CreatePopupMenu
E:\
8168\vc98\mfc\mfc\include\afxwin1.inl
1009

ShowYItemMenu
E:\testmemleak\mytest.cpp
100
  
這里省略了其他的函數(shù)調(diào)用

如此,我們很容易找到發(fā)生問題的函數(shù)是ShowYItemMenu()。當(dāng)使用MFC之類的類庫編程時(shí),大部分的API調(diào)用都被封裝在類庫的class里,有了Call Stack信息,我們就可以非常容易的追蹤到真正發(fā)生泄漏的代碼。

  記錄Call Stack信息會(huì)使程序的運(yùn)行變得非常慢,因此默認(rèn)情況下BoundsChecker不會(huì)記錄Call Stack信息。可以按照以下的步驟打開記錄Call Stack信息的選項(xiàng)開關(guān):

  1. 打開菜單:BoundsChecker|Setting…

  2. 在Error Detection頁中,在Error Detection Scheme的List中選擇Custom

  3. 在Category的Combox中選擇 Pointer and leak error check

  4. 鉤上Report Call Stack復(fù)選框

  5. 點(diǎn)擊Ok

  基于Code Injection,BoundsChecker還提供了API Parameter的校驗(yàn)功能,memory over run等功能。這些功能對(duì)于程序的開發(fā)都非常有益。由于這些內(nèi)容不屬于本文的主題,所以不在此詳述了。

  盡管BoundsChecker的功能如此強(qiáng)大,但是面對(duì)隱式內(nèi)存泄漏仍然顯得蒼白無力。所以接下來我們看看如何用Performance Monitor檢測(cè)內(nèi)存泄漏。

  使用Performance Monitor檢測(cè)內(nèi)存泄漏

  NT的內(nèi)核在設(shè)計(jì)過程中已經(jīng)加入了系統(tǒng)監(jiān)視功能,比如CPU的使用率,內(nèi)存的使用情況,I/O操作的頻繁度等都作為一個(gè)個(gè)Counter,應(yīng)用程序可以通過讀取這些Counter了解整個(gè)系統(tǒng)的或者某個(gè)進(jìn)程的運(yùn)行狀況。Performance Monitor就是這樣一個(gè)應(yīng)用程序。

  為了檢測(cè)內(nèi)存泄漏,我們一般可以監(jiān)視Process對(duì)象的Handle Count,Virutal Bytes 和Working Set三個(gè)Counter。Handle Count記錄了進(jìn)程當(dāng)前打開的HANDLE的個(gè)數(shù),監(jiān)視這個(gè)Counter有助于我們發(fā)現(xiàn)程序是否有Handle泄漏;Virtual Bytes記錄了該進(jìn)程當(dāng)前在虛地址空間上使用的虛擬內(nèi)存的大小,NT的內(nèi)存分配采用了兩步走的方法,首先,在虛地址空間上保留一段空間,這時(shí)操作系統(tǒng)并沒有分配物理內(nèi)存,只是保留了一段地址。然后,再提交這段空間,這時(shí)操作系統(tǒng)才會(huì)分配物理內(nèi)存。所以,Virtual Bytes一般總大于程序的Working Set。監(jiān)視Virutal Bytes可以幫助我們發(fā)現(xiàn)一些系統(tǒng)底層的問題; Working Set記錄了操作系統(tǒng)為進(jìn)程已提交的內(nèi)存的總量,這個(gè)值和程序申請(qǐng)的內(nèi)存總量存在密切的關(guān)系,如果程序存在內(nèi)存的泄漏這個(gè)值會(huì)持續(xù)增加,但是Virtual Bytes卻是跳躍式增加的。

  監(jiān)視這些Counter可以讓我們了解進(jìn)程使用內(nèi)存的情況,如果發(fā)生了泄漏,即使是隱式內(nèi)存泄漏,這些Counter的值也會(huì)持續(xù)增加。但是,我們知道有問題卻不知道哪里有問題,所以一般使用Performance Monitor來驗(yàn)證是否有內(nèi)存泄漏,而使用BoundsChecker來找到和解決。

  當(dāng)Performance Monitor顯示有內(nèi)存泄漏,而BoundsChecker卻無法檢測(cè)到,這時(shí)有兩種可能:第一種,發(fā)生了偶發(fā)性內(nèi)存泄漏。這時(shí)你要確保使用Performance Monitor和使用BoundsChecker時(shí),程序的運(yùn)行環(huán)境和操作方法是一致的。第二種,發(fā)生了隱式的內(nèi)存泄漏。這時(shí)你要重新審查程序的設(shè)計(jì),然后仔細(xì)研究Performance Monitor記錄的Counter的值的變化圖,分析其中的變化和程序運(yùn)行邏輯的關(guān)系,找到一些可能的原因。這是一個(gè)痛苦的過程,充滿了假設(shè)、猜想、驗(yàn)證、失敗,但這也是一個(gè)積累經(jīng)驗(yàn)的絕好機(jī)會(huì)。

  總結(jié)

  內(nèi)存泄漏是個(gè)大而復(fù)雜的問題,即使是Java和.Net這樣有Gabarge Collection機(jī)制的環(huán)境,也存在著泄漏的可能,比如隱式內(nèi)存泄漏。由于篇幅和能力的限制,本文只能對(duì)這個(gè)主題做一個(gè)粗淺的研究。其他的問題,比如多模塊下的泄漏檢測(cè),如何在程序運(yùn)行時(shí)對(duì)內(nèi)存使用情況進(jìn)行分析等等,都是可以深入研究的題目。如果您有什么想法,建議或發(fā)現(xiàn)了某些錯(cuò)誤,歡迎和我交流。


posted on 2006-10-19 13:45 泡泡牛 閱讀(9180) 評(píng)論(2)  編輯 收藏 引用 所屬分類: Develop

評(píng)論

# re: 用BoundsChecker檢測(cè)內(nèi)存泄漏 (zz)  2008-10-10 16:02 Pfeng

大俠,請(qǐng)問您對(duì)查找C#的內(nèi)存泄漏是否有好的辦法?TKS!
MSN: P.feng@hotmail.com

# re: 用BoundsChecker檢測(cè)內(nèi)存泄漏 (zz)  2008-12-03 15:53 紫羅

boundschecker支持什么編譯器呢?
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            欧美国产日本| 久久精品一二三| 亚洲精品护士| 国产日韩欧美视频| 久久九九全国免费精品观看| 亚洲裸体在线观看| 亚洲国产精品嫩草影院| 久久视频在线视频| 久久一综合视频| 久久久午夜精品| 久久久久国产精品麻豆ai换脸| 亚洲娇小video精品| 亚洲人成人一区二区三区| 91久久国产自产拍夜夜嗨 | 欧美精品v日韩精品v国产精品| 久久久久久综合| 久久中文久久字幕| 欧美国产在线观看| 国产精品夫妻自拍| 国产精品视频免费观看| 国产日韩亚洲欧美综合| 国内精品久久久久影院优| 狠狠狠色丁香婷婷综合久久五月| 在线不卡中文字幕播放| 最新亚洲激情| 国内精品一区二区| 亚洲成色777777女色窝| 亚洲免费高清| 亚洲欧美在线磁力| 美日韩精品免费观看视频| 亚洲激情视频在线播放| 在线一区二区三区四区| 久久精品成人欧美大片古装| 欧美交受高潮1| 国产欧美 在线欧美| 影音先锋亚洲精品| 一区二区精品在线| 久久精品国产久精国产一老狼 | 在线中文字幕日韩| 性欧美在线看片a免费观看| 久久精品一区二区三区四区 | 欧美成人免费大片| 欧美激情亚洲另类| 嫩草影视亚洲| 一区二区三区日韩精品| 久久激情视频久久| 国产精品久久久久久久久免费| 一区三区视频| 韩国在线一区| 亚洲主播在线播放| 欧美一区二区大片| 亚洲精品日本| 久久精品首页| 国产伦精品一区二区三区| 亚洲精品乱码久久久久久日本蜜臀| 亚洲人成在线播放| 久久精品国产77777蜜臀| 亚洲精品偷拍| 欧美成人精品| 欧美午夜女人视频在线| 亚洲国产另类久久久精品极度| 欧美在线不卡视频| 99国产精品久久久久久久成人热| 久久久噜久噜久久综合| 亚洲卡通欧美制服中文| 久久综合激情| 99视频有精品| 欧美成人在线免费观看| 亚洲国产小视频| 美国成人毛片| 久久亚洲影音av资源网| 亚洲欧洲一区二区三区| 亚洲国产日韩一区二区| 欧美www在线| 亚洲精品一区二区三区99| 91久久黄色| 欧美日韩精品在线播放| 亚洲一区二三| 欧美一级片在线播放| 国产一区二区三区直播精品电影| 久久婷婷国产综合尤物精品| 免费欧美在线视频| av成人黄色| 亚洲伊人伊色伊影伊综合网 | 亚洲四色影视在线观看| 夜夜嗨av一区二区三区免费区| 欧美色欧美亚洲高清在线视频| 欧美专区日韩视频| 久久综合网hezyo| 在线视频一区观看| 久久激情网站| 亚洲视频高清| 日韩午夜黄色| 亚洲午夜在线观看视频在线| 一区二区欧美亚洲| 国产日韩精品在线| 欧美.www| 国产精品草草| 你懂的亚洲视频| 国产精品入口| 亚洲日本久久| 国产午夜一区二区三区| 亚洲激情黄色| 伊人蜜桃色噜噜激情综合| 一区二区电影免费观看| 极品少妇一区二区三区| 亚洲精品在线免费观看视频| 好吊一区二区三区| 一区二区欧美国产| 亚洲精品视频在线播放| 久久久久成人精品免费播放动漫| 亚洲性感美女99在线| 母乳一区在线观看| 快she精品国产999| 国产精品影院在线观看| 夜夜夜精品看看| av成人黄色| 欧美高清视频| 欧美激情一区二区三区蜜桃视频 | 国产综合香蕉五月婷在线| 91久久在线| 亚洲日本成人| 久久亚洲影院| 免费在线观看精品| 国产真实久久| 欧美亚洲免费在线| 欧美一区二区在线免费播放| 国产精品初高中精品久久| 亚洲美女精品久久| 亚洲欧洲免费视频| 欧美www视频在线观看| 欧美国产三区| 亚洲精品一区在线| 欧美大片在线观看一区二区| 欧美大片免费久久精品三p | 亚洲影音先锋| 欧美伊人影院| 国产欧美亚洲精品| 欧美一区二区三区免费看| 久久精品国内一区二区三区| 国产麻豆精品视频| 午夜视频在线观看一区| 久久成人精品| 国模精品一区二区三区| 久久亚洲综合色| 亚洲国产成人在线播放| 91久久夜色精品国产九色| 免费成人黄色片| 亚洲国产成人porn| 一区二区国产精品| 国产精品区免费视频| 欧美一区二区成人6969| 欧美不卡视频一区发布| aa级大片欧美三级| 91久久精品日日躁夜夜躁国产| 亚洲激情视频在线观看| 欧美精品一线| 99热在线精品观看| 欧美日韩a区| 亚洲免费中文| 牛牛影视久久网| 亚洲无限av看| 国产婷婷97碰碰久久人人蜜臀| 久久精品国产一区二区三区| 亚洲高清毛片| 午夜亚洲一区| 国语自产精品视频在线看抢先版结局| 久久精品国产精品 | 亚洲精品欧美日韩专区| 欧美三级日本三级少妇99| 欧美一区成人| 最新成人av在线| 久久久久在线观看| 亚洲精选一区| 欧美日韩精品一区二区在线播放| 亚洲免费人成在线视频观看| 亚洲成色www久久网站| 欧美成人免费播放| 亚洲一区三区在线观看| 久久漫画官网| 亚洲午夜精品久久久久久app| 国产亚洲一本大道中文在线| 欧美成年人网站| 亚洲午夜在线观看| 久久久7777| 亚洲淫性视频| 亚洲精品一二区| 久久午夜av| 亚洲男人的天堂在线观看| 亚洲国产91| 黄色精品在线看| 国产精品久久久久久久午夜片| 欧美成人tv| 噜噜噜躁狠狠躁狠狠精品视频 | 免费日韩成人| 久久美女艺术照精彩视频福利播放| 国产精品yjizz| 欧美人与性动交α欧美精品济南到| 久久久999国产| 亚洲综合二区|