一種用于動態(tài)檢測c/c++內(nèi)存泄露的方法及系統(tǒng)的制作方法
【專利摘要】本發(fā)明涉及計算機軟件安全分析領(lǐng)域,提供一種用于動態(tài)檢測C/C++內(nèi)存泄露的方法,所述方法包括如下步驟:截獲C/C++源程序中動態(tài)內(nèi)存的內(nèi)存管理函數(shù);在截獲的內(nèi)存管理函數(shù)中加入監(jiān)測代碼,分析程序所申請的內(nèi)存資源,推測出內(nèi)存泄露的原因并進行監(jiān)控;依據(jù)Valgrind工具內(nèi)存泄露的規(guī)則,確定系統(tǒng)中應用程序內(nèi)存泄露的原因并最終給出分析報告。本發(fā)明可動態(tài)檢測C/C++源程序中內(nèi)存錯誤的問題,從而解決靜態(tài)分析技術(shù)的缺陷。
【專利說明】
一種用于動態(tài)檢測C/C++內(nèi)存泄露的方法及系統(tǒng)
技術(shù)領(lǐng)域
[0001] 本發(fā)明涉及計算機軟件安全分析領(lǐng)域,尤其涉及一種用于動態(tài)檢測C/C++內(nèi)存泄 露的方法及系統(tǒng)。
【背景技術(shù)】
[0002] C++因其靈活性、高效性等特點一直以來都是主流程序設(shè)計語言之一。它與Java等 高級語言相比,在編程中程序員需要自己管理內(nèi)存,并對程序中所涉及的內(nèi)存操作有很清 晰的認識。內(nèi)存問題很難讓人察覺,特別是內(nèi)存泄漏,它不同于其他內(nèi)存錯誤,如多次釋放、 野指針、或者是數(shù)組越界等容易暴露出來,內(nèi)存泄漏錯誤一般隱藏得比較深,在數(shù)萬行的代 碼之中尋找內(nèi)存泄漏無異于大海撈針。因此借助內(nèi)存分析工具來檢驗內(nèi)存錯誤是非常具有 實用價值的,不僅能夠提高軟件的質(zhì)量,還能縮短軟件的開發(fā)周期。
[0003] -般地,內(nèi)存泄漏的檢測方法分為兩大類,一類是靜態(tài)檢測方法,另一類是動態(tài)檢 測方法。靜態(tài)檢測方法通過分析程序源代碼,模擬所有可能執(zhí)行路徑,判定程序可能執(zhí)行路 徑中存在的安全缺陷。這種方法無需實際執(zhí)行程序,克服了動態(tài)分析性能開銷較大的問題, 但是由于靜態(tài)分析無法精確判斷程序的輸入、環(huán)境變量等信息,模擬執(zhí)行路徑中可能存在 不可行路徑。因此,靜態(tài)分析方法較高的誤報率是至今未解的一個重要難題。動態(tài)檢測方法 主要原理是在程序中進行動態(tài)內(nèi)存分配時,在堆中作以標記。當程序退出并釋放所有已分 配的內(nèi)存時,檢查堆上殘留的對象,這些殘留的對象就是程序中泄漏的內(nèi)存。這種分析方法 能夠直接發(fā)現(xiàn)實際發(fā)生的程序缺陷。但是,動態(tài)特性要求實際執(zhí)行程序引入較大性能和時 間開銷,另外由于程序執(zhí)行的路徑覆蓋存在死角,檢測結(jié)果完備性不足,漏報率較高。
[0004] 動態(tài)檢測法的實現(xiàn)主要有以下幾種方法:第一種方法是通過重新編寫編譯器來實 現(xiàn)。重新編寫編譯器需要花費大量的時間,而且需要的人力和物力代價也很高。因此,幾乎 沒有采用該種方法來完成C++內(nèi)存泄露檢測的工具。第二種方法是對源代碼進行修改,通過 語法分析和語義分析,插入監(jiān)測代碼,將原始的源代碼轉(zhuǎn)換為新的源代碼。該種方法雖然實 現(xiàn)的代價比較低,但是由于源代碼的轉(zhuǎn)換需要人工參與,自動化程度低,而且得出的結(jié)果不 太理想,該種方法的應用范圍也不太廣泛。
【發(fā)明內(nèi)容】
[0005] 鑒于上述問題,提出了本發(fā)明,以便提供一種克服上述問題或至少部分地解決上 述問題的一種用于動態(tài)檢測C/C++內(nèi)存泄露的方法及系統(tǒng)。
[0006] 根據(jù)本發(fā)明的一個方面,提供一種用于動態(tài)檢測C/C++內(nèi)存泄露的方法,所述方法 包括如下步驟:
[0007] 截獲C/C++源程序中動態(tài)內(nèi)存的內(nèi)存管理函數(shù);
[0008] 在截獲的內(nèi)存管理函數(shù)中加入監(jiān)測代碼,分析程序所申請的內(nèi)存資源,推測出內(nèi) 存泄露的原因并進行監(jiān)控;
[0009] 依據(jù)Valgrind工具內(nèi)存泄露的規(guī)則,確定系統(tǒng)中應用程序內(nèi)存泄露的原因并最終 給出分析報告。
[0010] 進一步的,通過Valgrind工具提供的相關(guān)API獲取所述內(nèi)存管理函數(shù)的控制權(quán)。
[0011] 進一步的,所述監(jiān)測代碼為內(nèi)存信息塊,所述內(nèi)存信息塊記錄所述內(nèi)存管理函數(shù) 中所涉及的內(nèi)存相關(guān)信息,所述內(nèi)存相關(guān)信息包括內(nèi)存的大小,返回給用戶內(nèi)存塊首地址、 申請的時間、當前堆棧中最近幾層函數(shù)的調(diào)用地址。
[0012] 根據(jù)本發(fā)明的另一方面,提供一種用于動態(tài)檢測C/C++內(nèi)存泄露的系統(tǒng),所述系統(tǒng) 包括內(nèi)存管理函數(shù)接口模塊、內(nèi)存信息塊管理模塊、內(nèi)存泄露檢測模塊和日志輸出模塊,其 中:
[0013]所述內(nèi)存管理函數(shù)接口模塊,用于對C/C++源程序中內(nèi)存管理函數(shù)進行捕獲和記 錄,從而獲得這些函數(shù)的控制權(quán);
[0014] 所述內(nèi)存信息塊管理模塊,用于記錄C/C++源程序中申請或釋放的動態(tài)內(nèi)存塊的 相關(guān)信息的數(shù)據(jù)結(jié)構(gòu);
[0015] 所述內(nèi)存泄露檢測模塊,用于對內(nèi)存泄露的類型進行檢測;
[0016] 所述日志輸出模塊,用于輸出內(nèi)存泄露錯誤信息并提供可以定位到內(nèi)存泄露具體 位置的信息。
[0017] 進一步的,所述內(nèi)存管理函數(shù)接口模塊,具體通過截獲C/C++程序中對應的符號信 息來獲取到該函數(shù)的控制權(quán)限。
[0018] 進一步的,每一個函數(shù)族都有一個完全屬于本函數(shù)族的內(nèi)存信息塊鏈表,所有的 函數(shù)族表頭都鏈成一個鏈表,由全局指針索引;同時,采用生命周期法需要將程序中分配的 所有內(nèi)存信息塊統(tǒng)一進行分組管理,以執(zhí)行到內(nèi)存分配函數(shù)時當前堆棧中的最近五層函數(shù) 返回地址作為關(guān)鍵字進行分組。
[0019] 進一步的,在系統(tǒng)截獲申請函數(shù)后,將內(nèi)存信息塊加入管理列表,具體流程包括: 記錄當前分配時間,將當前堆棧中的最近五層函數(shù)返回地址的異或值作為組號,判斷該組 號是否存在,如果存在,則將內(nèi)存信息塊加入該組并更新該組的相關(guān)信息;否則,將申請組 結(jié)點空間并初始化,將該組結(jié)點加入內(nèi)存信息塊管理列表中,同時將內(nèi)存信息塊加入該組, 并設(shè)置該組的相關(guān)信息。
[0020] 進一步的,在系統(tǒng)截獲釋放函數(shù)后,將內(nèi)存信息塊從管理列表中刪除,具體流程包 括:通過內(nèi)存塊管理信息中記錄的組號,找到該內(nèi)存塊所在的組;計算當前內(nèi)存塊的生存時 間,判斷該內(nèi)存信息塊的生存時間是否大于該組所保存的最大生命周期,如果是,則將該組 中最大生命周期更新為當前內(nèi)存塊的生存周期后,將該內(nèi)存信息塊從該組中刪除;否則,直 接將該內(nèi)存信息塊從該組中刪除。
[0021] 進一步的,當一個內(nèi)存塊的生存周期大于所在組中最大生命周期的兩倍則將該塊 內(nèi)存標記為疑似泄漏;在C/C++程序結(jié)束以后檢測各個函數(shù)族中是否還有沒有釋放的內(nèi)存 信息塊,如果有則表示存在內(nèi)存泄漏,報告內(nèi)存泄漏錯誤,內(nèi)存泄漏類型是確定泄漏。
[0022] 進一步的,所述系統(tǒng)還包括應用程序函數(shù)調(diào)用跟蹤模塊,用于在加入監(jiān)測代碼后, 對動態(tài)內(nèi)存使用情況進行跟蹤,并將動態(tài)內(nèi)存使用信息輸出給內(nèi)存信息塊管理模塊。
[0023]本發(fā)明可動態(tài)檢測C/C++源程序中內(nèi)存錯誤的問題,從而解決靜態(tài)分析技術(shù)的缺 陷。
【附圖說明】
[0024] 為了更清楚地說明本發(fā)明實施例的技術(shù)方案,下面將對實施例描述中所需要使用 的附圖作簡單地介紹,顯而易見地,下面描述中的附圖僅僅是本發(fā)明的一些實施例,對于本 領(lǐng)域普通技術(shù)人員來講,在不付出創(chuàng)造性勞動性的前提下,還可以根據(jù)這些附圖獲得其他 的附圖。
[0025] 圖1為本發(fā)明一種實施例的一種用于動態(tài)檢測C/C++內(nèi)存泄露方法的流程示意圖。
[0026] 圖2為本發(fā)明一種實施例的一種用于動態(tài)檢測C/C++內(nèi)存泄露系統(tǒng)的框架示意圖。 [0027]圖3為本發(fā)明一種實施例的一種用于動態(tài)檢測C/C++內(nèi)存泄露系統(tǒng)的功能結(jié)構(gòu)示 意圖。
[0028]圖4為本發(fā)明一種實施例的一種用于動態(tài)檢測C/C++內(nèi)存泄露系統(tǒng)在加入內(nèi)存信 息塊時的處理流程示意圖。
[0029]圖5為本發(fā)明一種實施例的一種用于動態(tài)檢測C/C++內(nèi)存泄露系統(tǒng)在刪除內(nèi)存信 息塊時的處理流程示意圖。
【具體實施方式】
[0030] 下面將參照附圖更詳細的描述本發(fā)明的示例性實施例。雖然附圖中顯示了本發(fā)明 的示例性實施例,然而應當理解,可以以各種形式實現(xiàn)本發(fā)明,而不應被這里闡述的實施例 所限制。相反,提供這些實施例是為了能更透徹的理解本發(fā)明,并且能夠?qū)⒈景l(fā)明的范圍完 整的傳達給本領(lǐng)域的技術(shù)人員。
[0031] 本發(fā)明的動態(tài)檢測方法是對中間代碼進行修改,即在編譯或鏈接階段插入監(jiān)測代 碼。這種方法的實現(xiàn)代價介于現(xiàn)有技術(shù)中提到的第一種方法和第二種方法之間,而且自動 化程度很高,得出來的結(jié)果比較令人滿意。
[0032] Valgrind工具的檢測原理是通過修改可執(zhí)行文件來進行內(nèi)存泄露檢測,所以不需 要重新編譯程序。但它并不是在執(zhí)行前對可執(zhí)行文件和所有相關(guān)的共享庫進行一次性修 改,而是和應用程序在同一個進程中運行,動態(tài)地修改即將執(zhí)行的下一段代碼。Valgrind是 插件式設(shè)計的,它的Core部分負責對應用程序的整體控制,并把即將修改的代碼,轉(zhuǎn)換成一 種中間格式,這種格式類似于RISC指令,然后把中間代碼傳給插件。插件根據(jù)要求對中間代 碼修改,然后把修改后的結(jié)果交給Core <Xore接下來把修改后的中間代碼轉(zhuǎn)換成原始的x86 指令,并執(zhí)行它。
[0033]基于以上原理,本發(fā)明在檢測程序存在的內(nèi)存問題時首先截獲內(nèi)存操作信息,即 截獲相關(guān)內(nèi)存管理函數(shù)的控制權(quán),如C中的操作符mall〇C、free等,C++中的操作符new、 delete等。獲得內(nèi)存管理函數(shù)的控制權(quán)以后,采取監(jiān)控和替換的方式在被測程序中添加插 粧代碼,記錄內(nèi)存的操作行為,包括記錄內(nèi)存相關(guān)信息(比如內(nèi)存的大小,返回給用戶內(nèi)存 塊首地址、申請的時間、當前堆棧中最近幾層函數(shù)的調(diào)用地址等),并對這些信息進行統(tǒng)一 管理。記錄內(nèi)存相關(guān)信息后,利用Valgrind工具的判定內(nèi)存泄露的規(guī)則和方法來判定內(nèi)存 出現(xiàn)的錯誤。本發(fā)明檢測出內(nèi)存錯誤后,報告內(nèi)存相關(guān)錯誤并提供可以定位該錯誤的相關(guān) fg息。
[0034]具體的,根據(jù)本發(fā)明的一個方面,提供一種用于動態(tài)檢測C/C++內(nèi)存泄露的方法, 如圖1所示,所述方法包括如下步驟:
[0035] 步驟S110,截獲C/C++源程序中動態(tài)內(nèi)存的內(nèi)存管理函數(shù),即捕獲和記錄C/C++源 程序中動態(tài)內(nèi)存的申請函數(shù)和釋放函數(shù)。具體的,通過V a 1 g r i n d工具提供的相關(guān)A PI (Application Programming Interface,應用程序編程接口),獲取應用程序中與內(nèi)存相關(guān) 函數(shù)的控制權(quán)。
[0036]步驟S120,在截獲的內(nèi)存管理函數(shù)中加入監(jiān)測代碼,分析程序所申請的內(nèi)存資源, 推測出內(nèi)存泄露的原因并進行監(jiān)控。具體的,獲取執(zhí)行權(quán)限以后,在截獲的內(nèi)存管理函數(shù)中 插入插粧代碼來對內(nèi)存相關(guān)操作進行監(jiān)控。比如對截獲的內(nèi)存申請函數(shù)來說,用插入一個 數(shù)據(jù)結(jié)構(gòu)(比如內(nèi)存信息塊)記錄該函數(shù)中所涉及的內(nèi)存相關(guān)信息,如申請內(nèi)存的大小,返 回給用戶內(nèi)存塊首地址、申請的時間、當前堆棧中最近幾層函數(shù)的調(diào)用地址等,監(jiān)測并推測 出內(nèi)存泄露的原因。
[0037]步驟S130,依據(jù)Va 1 gr ind工具內(nèi)存泄露的規(guī)則,確定系統(tǒng)中應用程序內(nèi)存泄露的 原因并最終給出分析報告。
[0038]根據(jù)本發(fā)明的另一方面,提供一種用于動態(tài)檢測C/C++內(nèi)存泄露的系統(tǒng),該系統(tǒng)、 valgrind以及C/C++源程序的關(guān)系如圖2所示,檢測系統(tǒng)截獲應用程序(C/C++)中的申請函 數(shù)和釋放函數(shù),插入監(jiān)測代碼統(tǒng)一進行內(nèi)存管理,對于申請函數(shù),將內(nèi)存信息塊加入管理列 表;對于釋放函數(shù),將內(nèi)存信息塊從管理列表中刪除,推測出內(nèi)存泄露的原因并進行監(jiān)控。 之后,利用Valgrind工具內(nèi)存泄露的規(guī)則,最終確定出系統(tǒng)中應用程序內(nèi)存泄露的原因,并 最終給出分析報告。
[0039]如圖3所示,一種用于動態(tài)檢測C/C++內(nèi)存泄露的系統(tǒng),具體包括內(nèi)存管理函數(shù)接 口模塊31、內(nèi)存信息塊管理模塊32、內(nèi)存泄露檢測模塊33和日志輸出模塊34。其中內(nèi)存管理 函數(shù)接口模塊31是檢測系統(tǒng)和被測程序的接口模塊,日志輸出模塊34是檢測系統(tǒng)和用戶的 交互模塊,內(nèi)存信息塊管理模塊32是本發(fā)明的核心。具體闡述如下:
[0040]內(nèi)存管理函數(shù)接口模塊31,用于對C/C++源程序中內(nèi)存管理函數(shù)進行捕獲和記錄, 從而獲得這些函數(shù)的控制權(quán)。C/C++動態(tài)內(nèi)存接管在定位函數(shù)信息時,需要確認函數(shù)的符號 信息,通過找到指定的符號來確定函數(shù)調(diào)用的起始處。比如,對于C++中分配動態(tài)內(nèi)存的new 和new[]在不同編譯器中編譯的符號不一樣,通過編寫一段只包含new[]和deleted的小程 序來查看當前編譯器編譯出的符號信息,在Linux環(huán)境中采用將該程序編譯成匯編文件,再 查找匯編文件中的指令,便可知在該編譯器下對應的符號信息,在C++程序中通過截獲對應 的符號信息就可以獲取到該函數(shù)的控制權(quán)限。
[0041]內(nèi)存信息塊管理模塊32,用于記錄C/C++源程序中申請或釋放的動態(tài)內(nèi)存塊的相 關(guān)信息的數(shù)據(jù)結(jié)構(gòu)。對于不同函數(shù)族申請的內(nèi)存信息塊放在一個全局鏈表中進行管理比較 混亂而且不容易區(qū)分,因此采用以函數(shù)族為單位的管理方式來解決此問題。每一個函數(shù)族 都有一個完全屬于本函數(shù)族的內(nèi)存信息塊鏈表,所有的函數(shù)族表頭都鏈成一個鏈表,由全 局指針索引。本發(fā)明采用內(nèi)存塊的生命周期法解決運行過程中的內(nèi)存泄漏問題。采用生命 周期法需要將程序中分配的所有內(nèi)存信息塊統(tǒng)一進行分組管理,以執(zhí)行到內(nèi)存分配函數(shù)時 當前堆棧中的最近五層函數(shù)返回地址作為關(guān)鍵字進行分組。
[0042]結(jié)合圖4和圖5,可理解內(nèi)存信息塊的加入流程和刪除流程。如圖4所示,在系統(tǒng)截 獲申請函數(shù)后,將內(nèi)存信息塊加入管理列表,具體流程包括:記錄當前分配時間,將當前堆 棧中的最近五層函數(shù)返回地址的異或值作為組號,判斷該組號是否存在,如果存在,則將內(nèi) 存信息塊加入該組并更新該組的相關(guān)信息;否則,將申請組結(jié)點空間并初始化,將該組結(jié)點 加入內(nèi)存信息塊管理列表中,同時將內(nèi)存信息塊加入該組,并設(shè)置該組的相關(guān)信息。如圖5 所示,在系統(tǒng)截獲釋放函數(shù)后,將內(nèi)存信息塊從管理列表中刪除,具體流程包括:通過內(nèi)存 塊管理信息中記錄的組號,找到該內(nèi)存塊所在的組;計算當前內(nèi)存塊的生存時間(生存周 期),判斷該內(nèi)存信息塊的生存時間是否大于該組所保存的最大生命周期,如果是,則將該 組中最大生命周期更新為當前內(nèi)存塊的生存周期后,將該內(nèi)存信息塊從該組中刪除;否則, 直接將該內(nèi)存信息塊從該組中刪除。
[0043] 在很多C/C++程序中,對動態(tài)內(nèi)存的申請和釋放都有一定的規(guī)律性,將內(nèi)存塊依據(jù) 函數(shù)的調(diào)用關(guān)系來分組,可以認為同一組內(nèi)存的內(nèi)存塊具有相似的行為,也即生存周期應 該大致相同。如果有一個組中的內(nèi)存塊生存周期大大超過本組的其他內(nèi)存塊的生存周期, 則可以認為這塊內(nèi)存是可能泄漏的內(nèi)存,稱為疑似泄漏。內(nèi)存泄漏的判定,是約定當一個內(nèi) 存塊的生存周期大于所在組中最大生命周期的兩倍則將該塊內(nèi)存標記為疑似泄漏,然后再 對該內(nèi)存塊進行是否有讀寫操作的判定,如果該內(nèi)存塊在一段時間內(nèi)都沒有寫操作,就認 為該內(nèi)存塊可能是泄漏的內(nèi)存,將該內(nèi)存塊報告為泄漏的內(nèi)存塊,類型為疑似泄漏。
[0044] C/C++程序結(jié)束以后檢測各個函數(shù)族中是否還有沒有釋放的內(nèi)存信息塊,如果有 則表示存在內(nèi)存泄漏,報告內(nèi)存泄漏錯誤,內(nèi)存泄漏類型是確定泄漏。
[0045]內(nèi)存塊管理的算法如下表所示:
[0048]內(nèi)存泄露檢測模塊33,用于對內(nèi)存泄露的類型進行檢測。內(nèi)存泄露主要包括內(nèi)存 泄露、內(nèi)存越界訪問、內(nèi)存多重釋放以及內(nèi)存不匹配釋放等錯誤。內(nèi)存塊管理模塊給出內(nèi)存 塊管理信息,內(nèi)存泄露檢測模塊依據(jù)valgrind的內(nèi)存泄露的判斷規(guī)則和方法,給出內(nèi)存泄 露的錯誤類型,并將錯誤類型報告給日志輸出模塊。
[0049] 日志輸出模塊34,用于輸出內(nèi)存泄露錯誤信息并提供可以定位到內(nèi)存泄露具體位 置的信息。日志輸出模塊34是檢測系統(tǒng)與用戶的交互模塊,內(nèi)存泄露檢測模塊將內(nèi)存泄露 錯誤類型報告給日志輸出模塊,日志輸出模塊依據(jù)這些信息輸出內(nèi)存泄露錯誤信息并提供 可以定位到內(nèi)存泄露具體位置的信息。
[0050] 作為上述實施例的進一步改進,一種用于動態(tài)檢測C/C++內(nèi)存泄露的系統(tǒng)還包括 應用程序函數(shù)調(diào)用跟蹤模塊35,用于在加入監(jiān)測代碼后,對動態(tài)內(nèi)存使用情況進行跟蹤,并 將動態(tài)內(nèi)存使用信息輸出給內(nèi)存信息塊管理模塊。
[0051] 本發(fā)明針對C/C++程序常出現(xiàn)的內(nèi)存泄漏、內(nèi)存越界訪問、內(nèi)存的不匹配釋放等錯 誤進行了研究,分析了現(xiàn)有的內(nèi)存錯誤檢測工具和方法,在基于開源的動態(tài)插粧框架工具 Valgrind的基礎(chǔ)上,采用函數(shù)族的內(nèi)存信息塊管理方法和生命周期法,實現(xiàn)了在Linux平臺 下運行的內(nèi)存檢測工具。該工具能有效地檢測出內(nèi)存泄漏、內(nèi)存越界訪問、內(nèi)存的不匹配釋 放等問題。
[0052]本說明書中的各個實施例均采用遞進的方式描述,各個實施例之間相同相似的部 分互相參見即可,每個實施例重點說明的都是與其他實施例的不同之處。尤其,對于裝置或 系統(tǒng)實施例而言,由于其基本相似于方法實施例,所以描述得比較簡單,相關(guān)之處參見方法 實施例的部分說明即可。以上所描述的裝置及系統(tǒng)實施例僅僅是示意性的,其中所述作為 分離部件說明的單元可以是或者也可以不是物理上分開的,作為單元顯示的部件可以是或 者也可以不是物理單元,即可以位于一個地方,或者也可以分布到多個網(wǎng)絡(luò)單元上。可以根 據(jù)實際的需要選擇其中的部分或者全部模塊來實現(xiàn)本實施例方案的目的。本領(lǐng)域普通技術(shù) 人員在不付出創(chuàng)造性勞動的情況下,即可以理解并實施。
[0053]以上所述僅為本發(fā)明之較佳實施例,并非用以限定本發(fā)明的權(quán)利要求保護范圍。 同時以上說明,對于相關(guān)技術(shù)領(lǐng)域的技術(shù)人員應可以理解及實施,因此其他基于本發(fā)明所 揭示內(nèi)容所完成的等同改變,均應包含在本權(quán)利要求書的涵蓋范圍內(nèi)。
【主權(quán)項】
1. 一種用于動態(tài)檢測C/C++內(nèi)存泄露的方法,所述方法包括如下步驟: 截獲C/C++源程序中動態(tài)內(nèi)存的內(nèi)存管理函數(shù); 在截獲的內(nèi)存管理函數(shù)中加入監(jiān)測代碼,分析程序所申請的內(nèi)存資源,推測出內(nèi)存泄 露的原因并進行監(jiān)控; 依據(jù)Valgrind工具內(nèi)存泄露的規(guī)則,確定系統(tǒng)中應用程序內(nèi)存泄露的原因并最終給出 分析報告。2. 根據(jù)權(quán)利要求1所述的一種用于動態(tài)檢測C/C++內(nèi)存泄露的方法,其特征在于:通過 Valgrind工具提供的相關(guān)API獲取所述內(nèi)存管理函數(shù)的控制權(quán)。3. 根據(jù)權(quán)利要求1所述的一種用于動態(tài)檢測C/C++內(nèi)存泄露的方法,其特征在于:所述 監(jiān)測代碼為內(nèi)存信息塊,所述內(nèi)存信息塊記錄所述內(nèi)存管理函數(shù)中所涉及的內(nèi)存相關(guān)信 息,所述內(nèi)存相關(guān)信息包括內(nèi)存的大小,返回給用戶內(nèi)存塊首地址、申請的時間、當前堆棧 中最近幾層函數(shù)的調(diào)用地址。4. 一種用于動態(tài)檢測C/C++內(nèi)存泄露的系統(tǒng),所述系統(tǒng)包括內(nèi)存管理函數(shù)接口模塊、內(nèi) 存信息塊管理模塊、內(nèi)存泄露檢測模塊和日志輸出模塊,其中: 所述內(nèi)存管理函數(shù)接口模塊,用于對C/C++源程序中內(nèi)存管理函數(shù)進行捕獲和記錄,從 而獲得這些函數(shù)的控制權(quán); 所述內(nèi)存信息塊管理模塊,用于記錄C/C++源程序中申請或釋放的動態(tài)內(nèi)存塊的相關(guān) 信息的數(shù)據(jù)結(jié)構(gòu); 所述內(nèi)存泄露檢測模塊,用于對內(nèi)存泄露的類型進行檢測; 所述日志輸出模塊,用于輸出內(nèi)存泄露錯誤信息并提供可以定位到內(nèi)存泄露具體位置 的信息。5. 根據(jù)權(quán)利要求4所述的一種用于動態(tài)檢測C/C++內(nèi)存泄露的系統(tǒng),其特征在于:所述 內(nèi)存管理函數(shù)接口模塊,具體通過截獲C/C++程序中對應的符號信息來獲取到該函數(shù)的控 制權(quán)限。6. 根據(jù)權(quán)利要求4所述的一種用于動態(tài)檢測C/C++內(nèi)存泄露的系統(tǒng),其特征在于:每一 個函數(shù)族都有一個完全屬于本函數(shù)族的內(nèi)存信息塊鏈表,所有的函數(shù)族表頭都鏈成一個鏈 表,由全局指針索引;同時,采用生命周期法需要將程序中分配的所有內(nèi)存信息塊統(tǒng)一進行 分組管理,以執(zhí)行到內(nèi)存分配函數(shù)時當前堆棧中的最近五層函數(shù)返回地址作為關(guān)鍵字進行 分組。7. 根據(jù)權(quán)利要求4所述的一種用于動態(tài)檢測C/C++內(nèi)存泄露的系統(tǒng),其特征在于:在系 統(tǒng)截獲申請函數(shù)后,將內(nèi)存信息塊加入管理列表,具體流程包括:記錄當前分配時間,將當 前堆棧中的最近五層函數(shù)返回地址的異或值作為組號,判斷該組號是否存在,如果存在,則 將內(nèi)存信息塊加入該組并更新該組的相關(guān)信息;否則,將申請組結(jié)點空間并初始化,將該組 結(jié)點加入內(nèi)存信息塊管理列表中,同時將內(nèi)存信息塊加入該組,并設(shè)置該組的相關(guān)信息。8. 根據(jù)權(quán)利要求4所述的一種用于動態(tài)檢測C/C++內(nèi)存泄露的系統(tǒng),其特征在于:在系 統(tǒng)截獲釋放函數(shù)后,將內(nèi)存信息塊從管理列表中刪除,具體流程包括:通過內(nèi)存塊管理信息 中記錄的組號,找到該內(nèi)存塊所在的組;計算當前內(nèi)存塊的生存時間,判斷該內(nèi)存信息塊的 生存時間是否大于該組所保存的最大生命周期,如果是,則將該組中最大生命周期更新為 當前內(nèi)存塊的生存周期后,將該內(nèi)存信息塊從該組中刪除;否則,直接將該內(nèi)存信息塊從該 組中刪除。9. 根據(jù)權(quán)利要求4所述的一種用于動態(tài)檢測C/C++內(nèi)存泄露的系統(tǒng),其特征在于:當一 個內(nèi)存塊的生存周期大于所在組中最大生命周期的兩倍則將該塊內(nèi)存標記為疑似泄漏;在 C/C++程序結(jié)束以后檢測各個函數(shù)族中是否還有沒有釋放的內(nèi)存信息塊,如果有則表示存 在內(nèi)存泄漏,報告內(nèi)存泄漏錯誤,內(nèi)存泄漏類型是確定泄漏。10. 根據(jù)權(quán)利要求4所述的一種用于動態(tài)檢測C/C++內(nèi)存泄露的系統(tǒng),其特征在于:所述 系統(tǒng)還包括應用程序函數(shù)調(diào)用跟蹤模塊,用于在加入監(jiān)測代碼后,對動態(tài)內(nèi)存使用情況進 行跟蹤,并將動態(tài)內(nèi)存使用信息輸出給內(nèi)存信息塊管理模塊。
【文檔編號】G06F11/36GK105912458SQ201610184785
【公開日】2016年8月31日
【申請日】2016年3月28日
【發(fā)明人】朱朝陽, 崔寶江, 韓麗芳, 周亮, 齊俊鑫, 單松玲, 李凌, 李怡康
【申請人】中國電力科學研究院, 國家電網(wǎng)公司, 北京郵電大學