<listing id="vjp15"></listing><menuitem id="vjp15"></menuitem><var id="vjp15"></var><cite id="vjp15"></cite>
<var id="vjp15"></var><cite id="vjp15"><video id="vjp15"><menuitem id="vjp15"></menuitem></video></cite>
<cite id="vjp15"></cite>
<var id="vjp15"><strike id="vjp15"><listing id="vjp15"></listing></strike></var>
<var id="vjp15"><strike id="vjp15"><listing id="vjp15"></listing></strike></var>
<menuitem id="vjp15"><strike id="vjp15"></strike></menuitem>
<cite id="vjp15"></cite>
<var id="vjp15"><strike id="vjp15"></strike></var>
<var id="vjp15"></var>
<var id="vjp15"></var>
<var id="vjp15"><video id="vjp15"><thead id="vjp15"></thead></video></var>
<menuitem id="vjp15"></menuitem><cite id="vjp15"><video id="vjp15"></video></cite>
<var id="vjp15"></var><cite id="vjp15"><video id="vjp15"><thead id="vjp15"></thead></video></cite>
<var id="vjp15"></var>
<var id="vjp15"></var>
<menuitem id="vjp15"><span id="vjp15"><thead id="vjp15"></thead></span></menuitem>
<cite id="vjp15"><video id="vjp15"></video></cite>
<menuitem id="vjp15"></menuitem>

一種面向堆操作程序的內存泄漏檢測方法

文檔序號:6359524閱讀:262來源:國知局
專利名稱:一種面向堆操作程序的內存泄漏檢測方法
技術領域
本發明涉及計算機程序中一類具有動態、易變共享內存操作特性的堆操作程序內存泄漏的靜態檢測方法。
背景技術
堆操作程序包括使用動態數據結構(如鏈表、樹等)存儲和處理數據的程序,在系統軟件和應用軟件非常常見,比如操作系統(如Linux、FreeRTOS)常常使用優先級隊列或哈希表管理系統的任務;設備驅動管理程序使用共享單向或雙向鏈表管理各種設備;服務器軟件(如=Apache)使用容器(Collection)接受和存儲各種用戶請求;信息系統管理軟件使用各類容器表示視圖和存儲從數據庫中查詢得到的數據。這類程序都具有運行過程中動態分配、聚合、分離或釋放堆中內存單元的特點;另一方面,分析這類程序源代碼時可知,程序員使用指針變量(或指針域)直接(或間接)操縱這些內存單元,使得這些動態內存單元間存在著復雜的指向關系,比如某個內存單元可能被多個指針變量或其它內存單元所指向。因此,判斷堆操作程序中已申請的內存單元是否最終被釋放比其他類型的程序困難和復雜得多。內存泄漏是指動態分配的內存沒有即時被釋放,它是一類重要的軟件錯誤,它能夠導致持續運行的系統由于內存資源耗盡而崩潰,或者重要的信息泄漏。當前,內存泄漏檢測有多種方法及其工具,主要分為動態和靜態的方法。典型動態方法的工具有Purify、JPF等,這類方法雖能準確地定位錯誤,自動化程度高,但受限于輸入用例,不能檢查所有的內存泄漏錯誤;靜態方法是在不運行軟件前提下檢查是否存在內存泄漏,典型工作有LCLint、SATURN等,可以找到所有可能的內存泄漏錯誤,但是存在較高的誤報率。因此,如何在保證精度的前提下使得靜態檢測工具能夠檢測大規模程序是當前靜態檢測研究的熱點和難點。針對動態、易變分配內存的堆操作程序中內存泄漏檢測的方法主要可以分為(I)域不敏感檢測方法域不敏感檢測方法是基于指針別名分析檢測程序中每個分配的內存結點是否最終被釋放,又可以分為流敏感和流不敏感、路徑敏感和路徑不敏感、上下文敏感和上下文不敏感6種檢測方法。例如=Zongxing Xu等人在2008年軟件質量國際會議(QSIC' 08)上提出了基于約束求解器CVC3路徑敏感的過程間內存泄漏算法;Yungbum Jung和KwangkeunYi在國際內存管理論壇會議(ISMM’ 08)上提出了一種自動化的靜態分析工具SPARROW,設計了基于逃逸模型的參數化過程函數摘要方法;除此之外,Xie Yichen和Alex Aiken在第10屆歐洲軟件工程會議上提出了內存泄漏檢測工具Saturn,將內存泄漏問題規約為布爾公式的可滿足性問題,然后使用SAT求解器判斷是否存在內存泄漏;David LHeine等人在第28屆軟件工程國際會議上提出了內存泄漏檢測工具Clouseau,它是基于指針所有權描 述釋放堆內存結點的指針變量,然后構造所有權約束系統檢測內存泄漏錯誤。所有這些工具不能直接應用于檢測堆操作程序中內存泄漏錯誤。(2)域敏感檢測方法
域敏感檢測方法涉及到堆內存單元間的可達性關系。Mooly Sagiv等人在2002年ACM程序語言與系統匯刊(T0PLAS’ 02)上提出了三值邏輯TVLA (Three-Value Logic),對具有鏈表類型的程序通過定義核心(core)和輔助(instrumental)謂詞集將內存結點劃分成有限的等價類,通過分析程序的形態來證明各種鏈表操作程序沒有內存泄漏錯誤,然而TVLA應用于其他類型的堆操作程序內存泄漏檢測時存在比較高的誤報;Hackett等人在2005年ACM程序語言原理國際會議(P0PL’ 05)上提出了一種新穎的基于引用計數的區域形態分析算法,并能夠在2分鐘內對3個流行的幾萬行大型C程序進行檢測并發現97個錯誤,其中只有37個是真實錯誤,雖然效率比較高,但是,存在著較高的誤報率;Ji Wang等人在2009年計算機學報英文版(JCST’ 09)上設計了基于內存抽象指向圖需求驅動的內存泄漏檢測算法,并且在精度和效率上取得相對比較好的平衡,但是,存儲開銷和計算復雜度仍比較高。最近,相繼出現了對堆操作程序使用邏輯推理的形態分析方法檢測內存錯誤,典型工作有SpaceInvader和Xisa。SpaceInvader在2008年計算機輔助驗證國際會議(CAV’ 08)上使用分離邏輯(Separation Logic)公式遞歸定義鏈表數據結構不變式,然后基于遞歸定義設計了各種推理規則對堆操作程序進行推理,已經成功分析和驗證了Windows和Linux下一些設備驅動管理程序的內存正確性;Xisa在2008年ACM程序語言原理國際會議(P0PL’ 08)上使用抽象解釋框架支持參數化的用戶自定義數據結構不變式分析和驗證堆操作程序的內存安全性質。但是,這些方法受到用戶自定義數據結構不變式的約束,自動化程度不高,很難實用于大規模實際程序的內存錯誤自動檢測。綜上所述,雖然目前學術界和工業界有多種不同的內存泄漏檢測方法,每種方法都有各自的特點與適用范圍,但它們在檢測堆操作程序上均有不足之處。域不敏感的檢測方法雖能檢測大規模程序,但是檢測精度較低,尤其是面對具有堆內存聚合、分離特性的堆操作程序時,不能夠檢測同一指針變量指向內存區域中的所有內存結點是否全部被釋放;域敏感的檢測方法雖能檢測堆操作程序中所有內存泄漏錯誤,但是由于自動化程序不高或系統資源(主要包括內存、時間)消耗代價太大,所以效率不高,能夠分析的程序規模比較小。

發明內容
本發明要解決的技術問題是針對當前內存泄漏檢測方法在具有動態共享內存申請、合并、分離、刪除等操作特性的堆操作程序內存錯誤檢測方面存在精度和效率的問題,提供一種基于堆內存局部抽象的前向數據流迭代的內存泄漏檢測方法,提高檢測的精度和效率。具體技術方案為第I步,利用編譯器平臺對被檢測程序進行詞法分析、語法分析,生成被檢測程序的抽象語法樹、控制流圖(描述程序基本語句間的前后繼關系)、過程調用圖(程序中函數間的調用關系圖)這樣的中間信息。第2步,預處理。在對一個真實的堆操作程序內存檢測之前需要進行兩步預處理。2. I切片,即將那些沒有使用任何指針類型變量的賦值語句從程序中刪除,得到切片后的程序。 2. 2將經過切片后的程序中不符合標準形式的指針賦值語句按照轉換規則轉換成標準形式。標準形式的指針賦值語句包括7種1,將指針變量P置為空,形如P = null ;2,將指針變量P的指針域P- > fm置為空,形如P_ > fm = null ;3,指針變量間拷貝語句,形如P = q ;4,指針P與指針q的指針域間的拷貝語句,形如p = q- > fm ;5,指針p的指針域與指針q間的拷貝語句,形如p- > fm = q ;6,內存申請語句,形如p = malloc -J,內存釋放語句,形如free (p)。轉換規則有5種,分別是1,引入輔助指針變量Ptci將形如p- >fm = q- > fn的指針賦值語句轉換為ptQ = q- > fn ;p- > fm = ptQ ;2,引入輔助指針變量Pt1將形如P = p- > fm的指針賦值語句轉換為Wt1 = p- > fm ;p = Pt1 ;3,引入輔助指針變量pt2將形如p- > fm = malloc的指針賦值語句轉換為pt2 = malloc ;p- > fm = pt2 ;4,引入輔助指針變量Pt3將形如P = q_ > fm_ > fn的指針賦值語句轉換為pt3 = q- >fm ;p = Pt3-> fn ;5,引入輔助指針變量pt4將形如free(p-> fm)的內存釋放語句轉換為Pt4 = p- > fm ;free (pt4)。第3步,根據函數中每個指針變量的別名信息定義指針的擴展類型,得到程序的堆內存抽象狀態。堆操作程序中,指針變量P的擴展類型4定義為〈fl :〈dist ;2PV,;f2 :<dist,2PVar> ;. . . fi <dist ;2PVar>. · · ;fn <dist ;2PVar>>,其中f1; f2, . . . fi; . . . , fn 分別表示P指向內存單元中指針域的名字,I < i < η,即P指向由η個指針域聚集的內存單元,內存單元又稱為內存結點;變量dist表示堆中內存結點距離指針P的值;2PVm表示所有指向距離P所指向內存結點值為dist的內存結點構成的指針變量集,稱為指針別名集,包括全局指針變量、局部指針變量、函數中具有指針類型的形式參數。分析堆操作程序7種標準基本指針賦值語句可知一條指針賦值語句中P直接或間接引用的內存結點距離P的最大值為1,例如語句P- > = q,將指針P所指向的內存結點中指針域A的值修改為指針q所指向的內存結點的地址,在此語句中,P通過指針域A路由可達的內存結點距離P的值 為I。因此,變量dist值的范圍為0、1和2,其中元素O和I表示堆內存中距離P所指向的內存結點精確值,值2是一個抽象值,表示通過某個指針域兩次或兩次以上的路由次數(又稱指針解引用操作,dereferencing),在堆內存中這樣得到的內存結點又稱摘要結點(summary node)。指針集2PVar中有兩個特殊的元素空集0表示堆內存中沒有任何指針變量指向該內存單元,而該內存單元在堆內存中已經被分配;丄表示某個指針變量P或指針域fi的值為null (特殊標記值,表示該指針變量值為無效內存地址),P或指針域A所指向的內存單元在堆中還沒有被分配。堆操作程序HP的活性指針變量是程序片段中一類被使用或修改的指針變量,由謂詞LivePVar表示。所以,堆內存局部抽象狀態是具有活性指針變量的擴展類型構成的集合,即S ,公式中,Pi表示任意一個具有活性的指針變量,4表示Pi的擴展類型。由此可知堆操作程序中,堆內存局部抽象狀態的數目是有限的。假設堆操作程序中指針變量個數為pn,聚集類型中指針域的數目為fn,那么堆內存局部抽象狀態S 的最大數目為[fnX3X(2pn+l)]pn,公式中,3表示距離值的種類,2pn表示指針別名集的冪集中子集數,I表示加上指針別名集中特殊元素值丄。第4步,過程內內存泄漏檢測。根據上述指針擴展類型的定義,得到堆操作程序中基本語句關于堆內存抽象狀態的遷移關系,具體地,從被檢測程序的過程調用圖中自頂向下選擇某個函數f,并將函數f入口處的抽象狀態純設置為空,根據前向數據流迭代方法進行過程內內存泄漏檢測,前向數據流迭代方法是
4. I初始化函數f中每個程序點i的堆內存抽象狀態&,置為空,并將隊列W置為空,W是一個先進先出FIFO的隊列,基本元素為 〉對,S為語句。4. 2將函數f的入口語句S。和抽象狀態Sf1加入到隊列W。4. 3判斷隊列W是否為空,如果為空則轉第6步,如果不為空則執行4. 4。
4. 4從隊列W中彈出項〈S,S 〉,根據語句s的類型轉換抽象狀態釗,得到新的抽象狀態S丨,具體方法如下4. 4. I如果語句s為基本指針賦值語句,則按7種指針賦值語句的類型轉換狀態SB,得到新的抽象狀態S〖,并從Succ(s)中選擇某個元素s’,Succ(s)表示控制流圖中語句s的后繼語句集。然后執行4. 5。按7種指針賦值語句的類型轉換劍的方法是(I)指針賦值語句P = null。轉換規則是在狀態SB中,首先從通過某個指針域fi路由可達P指向內存結點的指針別名集中刪除P,然后將j置為null,SP :將j中所有通過A路由距離值為0、1和2的指針別名集置為丄,得到新的抽象狀態Stt1。如果狀態中指針P所指向的內存結點存在且沒有被其他指針變量或堆內存中其他內存結點通過某個指針域路由可達,則發生內存泄漏,將該語句s和抽象狀態劎加入到內存泄漏隊列heapleakListF中,heapleakListF是保存所有發生內存泄漏的語句和狀態的隊列,基本元素為語句和抽象狀態對〈S, S 〉。(2)語句p- > fm = null ο轉換規則是在狀態S 中,指針變量x代表能夠通過某個指針域A路由可達P指向內存結點的指針變量。首先,修改X的擴展類型如果X與P別名,即x到P的距離為0,則從中將通過&路由距離值為I和2的指針別名集置為空;如果X到P的距離值為I或2,則從τ|中通過&路由距離為2的指針別名集中刪除#中通過fi路由距離值為I和2的指針別名集。然后,將#中通過fm路由距離值為I和2的指針別名集置為空,得到新的抽象狀態蝴。如果狀態劎中P指向內存結點中的指向的內存結點存在且沒有被其他指針變量或其他內存結點通過A路由可達,則發生內存泄漏,將語句s和狀態加入到內存泄漏隊列heapleakListF中。(3)指針拷貝語句P = q。轉換規則是首先,在狀態SB下按照規則⑴執行語句P = null得到中間抽象狀態然后在中間抽象狀態下,將4賦值給4,即將P的指向修改為q指向的結點,得到新的抽象狀態Stt1。如果狀態中P指向的內存結點存在且沒有被其他指針變量或堆內存中其他內存結點通過某個指針域路由可達,則發生內存泄漏,將語句s和狀態加入到內存泄漏隊列heapleakListF中。(4)語句P = q_ > fm。轉換規則是首先,在狀態SB下按照規則⑴執行語句P=null得到中間抽象狀態然后在中間抽象狀態下,將4中通過路由距離值為I的指針別名集賦值給與4中通過某個指針域fi路由距離值為O的指針別名集,將P加入到4中通過&路由距離值為I的指針別名集中,得到新的抽象狀態蝴。如果狀態中P指向的內存結點存在且沒有被其他指針變量或堆內存中其他內存結點通過某個指針域路由可達,則發生內存泄漏,將語句s和狀態SB加入到內存泄漏隊列heapleakListF中。(5)語句P- > fm = q。轉換規則是首先,在狀態SB下按照規則⑴執行語句P- > fm = null得到中間抽象狀態然后在中間抽象狀態M下,集合Q表示#中通過某個指針域fi路由距離為O的指針別名集,指針變量t表示抽象狀態S'H中能夠通過fi 一次或多次路由到達P指向的內存結點的指針。按照以下規則修改中間抽象狀態首先,修改集合Q中每個指針變量y的擴展類型將4中通過fi路由距離為O的指針別名集加入到4中通過&路由距離為I的指針別名集中,將4中通過&路由距離為I和2的指針別名集添加到^中通過&路由距離為2的指針別名集中;然后,將通過&路由距離q值為0、1和2的指針別名集同q —起添加到j中通過&路由距離為2的指針別名集中,得到新的抽象狀態蝴。如果狀態中P指向的內存結點中f;指向的內存結點存在且沒有被其他指針變量或堆內存中其他內存結點通過某個指針域路由可達,則發生內存泄漏,將語句s和狀態S 加入到內存泄漏隊列heapleakListF中。(6)內存分配語句P = malloc O。轉換規則是首先,在狀態S 下按照規則(I)執行語句P = null得到中間抽象狀態然后在中間抽象狀態S'H下,新申請一個內存結 點并且將該內存結點的地址賦值給指針P,即將#中通過某個指針域fi路由距離為O的指針別名集置為空集0,通過A路由距離為I和2的指針別名集置為丄,得到新的抽象狀態Sb1。如果狀態SB中P指向的內存結點存在且沒有被其他指針變量或堆內存中其他內存結點通過某個指針域A路由可達,則發生內存泄漏,將語句s和狀態SB加入到內存泄漏隊列 heapleakListF 中。(7)內存釋放語句free (P)。轉換規則是在狀態S 中,指針變量w表示活指針變量集LivePVar (HP)中除P所有其他指針變量,首先,從#中通過某個指針域路由距離值為0、1和2的指針別名集中刪除4中通過fi路由距離為O的指針別名集,然后將#中通過fi路由距離值為0、1和2的指針別名集置為丄,得到新的抽象狀態Sb1。如果狀態釗中P指向內存結點中某個指針域所指向的內存結點存在沒有被其他指針變量或堆內存中其他內存結點通過某個指針域路由所可達,則發生內存泄漏,將語句s和狀態SB加入到內存泄漏隊列 heapleakListF 中。4. 4. 2如果語句s為switch條件選擇語句,則首先在當前堆內存抽象狀態刨下求解switch語句條件的真值,然后根據條件真值從Succ(s)中選擇下一條執行語句s’,并將S,作為語句s的后繼語句,狀態刨作為新的抽象狀態Sb1,執行4. 5。 4. 4. 3如果語句s為無條件跳轉語句,則并將目標語句S,作為語句s的后繼語句,狀態刨作為新的抽象狀態Sb1,執行4. 5。4. 4. 4如果語句s為函數調用語句,則執行第5步,得到新的抽象狀態Sb1,從Succ(S)中選擇某個元素s’,作為s的后繼語句。4. 4. 5如果語句s是函數返回語句return e,則在抽象狀態S嚇,將指針變量e的擴展類型作為函數返回值的擴展類型,全局指針變量的擴展類型不變,其他局部指針變量的擴展類型賦值置空,得到新的抽象狀態Stt1,并作為函數f的出口狀態蝴7,出口語句S,作為返回語句s的后繼語句,然后執行4. 5。4. 5將新的抽象狀態Sb1與后繼語句s’的初始狀態通過合并操作Join得到該程序點新的抽象狀態§1,執行4. 6步。為了盡可能地檢測出堆操作程序內存泄漏的錯誤,合并操作是當且僅當任意兩個抽象狀態s丨和4存在包括關系時才能合并,否則兩個抽象狀態分別作為合并操作的元素。兩個堆內存抽象狀態S丨和越存在包含關系s丨g s〖,當且僅當狀態s丨中任意元素在狀態越中。合并操作由公式可以表示為
權利要求
1.ー種面向堆操作程序的內存泄漏檢測方法,其特征在于包括以下步驟 第I步,利用編譯器平臺對被檢測程序進行詞法分析、語法分析,生成被檢測程序的抽象語法樹、控制流圖、過程調用圖; 第2步,預處理2.I切片,即將那些沒有使用任何指針類型變量的賦值語句從程序中刪除,得到切片后的程序;2.2將經過切片后的程序中不符合標準形式的指針賦值語句按照轉換規則轉換成標準形式; 第3步,根據函數中每個指針變量的別名信息定義指針的擴展類型,得到程序的堆內存抽象狀態;堆操作程序中,指針變量P的擴展類型定義4為Kf1 <dist ;2PVar> ;f2 <dist,2PVar> ;. . . fi <dist ;2PVar>. ;fn <dist ;2PVar》,其中 ^1, f2, . . . fi . . . , fn 分別表示P指向內存單元中指針域的名字,I < i < n,即p指向由n個指針域聚集的內存單元,內存單元又稱為內存結點;變量dist表示堆中內存結點距離指針p的值;2PVm表示所有指向距離P所指向內存結點值為dist的內存結點構成的指針變量集,稱為指針別名集;變量dist值的范圍為0、1和2,其中元素O和I表示堆內存中距離p所指向的內存結點精確值,值2是ー個抽象值,表示通過某個指針域も兩次或兩次以上的路由次數,在堆內存中這樣得到的內存結點又稱摘要結點;指針集2PVal:中有兩個特殊的元素空集0表示堆內存中沒有任何指針變量指向該內存単元,而該內存單元在堆內存中已經被分配;丄表示某個指針變量P或指針域も的值為null,表示該指針變量值為無效內存地址,p或指針域も所指向的內存單元在堆中還沒有被分配;堆操作程序HP的活性指針變量是程序片段中ー類被使用或修改的指針變量,由謂詞LivePVar表示;堆內存局部抽象狀態是具有活性指針變量的擴展類型構成的集合,即別,Pi表示任意ー個具有活性的指針變量,4表示Pi的擴展類型; 第4步,從被檢測程序的過程調用圖中自頂向下選擇某個函數f,并將函數f 入口處的抽象狀態郵設置為空,根據前向數據流迭代方法進行過程內內存泄漏檢測,得到堆操作程序中基本語句關于堆內存抽象狀態的遷移關系,前向數據流迭代方法是4. I初始化函數f中每個程序點i的堆內存抽象狀態置為空,并將隊列W置為空,W是ー個先進先出FIFO的隊列,基本元素為〈s,S 〉對,s為語句,SB為堆內存局部抽象狀態;4. 2將函數f的入口語句S0和抽象狀態Sf1加入到隊列W ;4. 3判斷隊列W是否為空,如果為空則轉第6歩,如果不為空則執行4. 4 ;4. 4從隊列W中彈出項〈 が〉,根據語句s的類型轉換抽象狀態別,得到新的抽象狀態蝴,具體方法如下4. 4. I如果語句s為基本指針賦值語句,則按7種指針賦值語句的類型轉換狀態SB,得到新的抽象狀態Stt1,并從控制流圖中語句s的后繼語句集Succ (S)中選擇某個元素s’,然后執行4. 5 ;按7種指針賦值語句的類型轉換SB的方法是 (I)指針賦值語句P = null,轉換規則是在狀態SB中,首先從通過某個指針域も路由可達P指向內存結點的指針別名集中刪除P,然后將d置為null,S卩將d中所有通過fi路由距離值為0、1和2的指針別名集置為丄,得到新的抽象狀態Stt1;如果狀態中指針P所指向的內存結點存在且沒有被其他指針變量或堆內存中其他內存結點通過某個指針域路由可達,則發生內存泄漏,將該語句S和抽象狀態SB加入到內存泄漏隊列heapleakListF中,heapleakListF是保存所有發生內存泄漏的語句和狀態的隊列,基本元素為語句和抽象狀態對〈s, S 〉; (2)語句p-> fm = null,轉換規則是在狀態中,指針變量X代表能夠通過某個指針域も路由可達P指向內存結點的指針變量;首先,修改X的擴展類型如果X與p別名,即x到P的距離為O,則從ァ|中將通過も路由距離值為I和2的指針別名集置為空;如果X到P的距離值為I或2,則從r|中通過fi路由距離為2的指針別名集中刪除4中通過fi路由距離值為I和2的指針別名集;然后,將ザ中通過fm路由距離值為I和2的指針別名集置為空,得到新的抽象狀態Sb1;如果狀態中P指向內存結點中的fm指向的內存結點存在且沒有被其他指針變量或其他內存結點通過も路由可達,則發生內存泄漏,將語句s和狀態加入到內存泄漏隊列heapleakListF中; (3)指針拷貝語句p= q,轉換規則是首先,在狀態SB下按照規則(I)執行語句P =null得到中間抽象狀態然后在中間抽象狀態下,將づ賦值給づ,即將p的指向修改為q指向的結點,得到新的抽象狀態SB1;如果狀態中P指向的內存結點存在且沒有被其他指針變量或堆內存中其他內存結點通過某個指針域路由可達,則發生內存泄漏,將語句s和狀態SB加入到內存泄漏隊列heapleakListF中; (4)語句p= q- > fm,轉換規則是首先,在狀態8 下按照規則⑴執行語句P = null得到中間抽象狀態沒《,然后在中間抽象狀態S/B下,將ザ中通過路由距離值為I的指針別名集賦值給與4中通過某個指針域fi路由距離值為O的指針別名集,將p加入到づ中通過も路由距離值為I的指針別名集中,得到新的抽象狀態SB1;如果狀態中P指向的內存結點存在且沒有被其他指針變量或堆內存中其他內存結點通過某個指針域路由可達,則發生內存泄漏,將語句s和狀態SB加入到內存泄漏隊列heapleakListF中; (5)語句P-> fm = q,轉換規則是首先,在狀態SB下按照規則⑴執行語句P- > fm=null得到中間抽象狀態然后在中間抽象狀態下,集合Q表示づ中通過某個指針域も路由距離為O的指針別名集,指針變量X表示抽象狀態中能夠通過も一次或多次路由到達P指向的內存結點的指針;按照以下規則修改中間抽象狀態首先,修改集合Q中指針變量y的擴展類型づ:將巧中通過も路由距離為O的指針別名集加入到づ中通過も路由距離為I的指針別名集中,將4中通過も路由距離為I和2的指針別名集添加到4中通過も路由距離為2的指針別名集中;然后,將通過も路由距離q值為0、1和2的指針別名集同q—起添加到ァ|中通過も路由距離為2的指針別名集中,得到新的抽象狀態Stt1;如果狀態SB中P指向的內存結點中fm指向的內存結點存在且沒有被其他指針變量或堆內存中其他內存結點通過某個指針域路由可達,則發生內存泄漏,將語句s和狀態加入到內存泄漏隊列heapleakListF中; (6)內存分配語句p= malloC(),轉換規則是首先,在狀態釗下按照規則(I)執行語句P = null得到中間抽象狀態然后在中間抽象狀態S'H下,新申請ー個內存結點并且將該內存結點的地址賦值給指針P,即將4中通過某個指針域も路由距離為O的指針別名集置為空集0,通過も路由距離為I和2的指針別名集置為丄,得到新的抽象狀態Sb1;如果狀態中P指向的內存結點存在且沒有被其他指針變量或堆內存中其他內存結點通過某個指針域fi路由可達,則發生內存泄漏,將語句S和狀態SB加入到內存泄漏隊列heapleakListF 中; (7)內存釋放語句free (p),轉換規則是在狀態中,指針變量w表示活指針變量集LivePVar(HP)中除p所有其他指針變量,首先,從赳中通過某個指針域も路由距離值為O、I和2的指針別名集中刪除ザ中通過も路由距離為O的指針別名集,然后將4中通過も路由距離值為0、1和2的指針別名集置為丄,得到新的抽象狀態SB1;如果狀態中P指向內存結點中某個指針域所指向的內存結點存在沒有被其他指針變量或堆內存中其他內存結點通過某個指針域路由所可達,則發生內存泄漏,將語句s和狀態S咖入到內存泄漏隊列heapleakListF 中; .4.4. 2如果語句s為switch條件選擇語句,則首先在當前堆內存抽象狀態刨下求解switch語句條件的真值,然后根據條件真值從Succ(s)中選擇下一條執行語句s’,并將s’作為語句s的后繼語句,狀態刨作為新的抽象狀態Sb1,執行4. 5 ; .4.4. 3如果語句s為無條件跳轉語句,則將目標語句S,作為語句s的后繼語句,狀態SB作為新的抽象狀態S〖,執行4. 5 ; .4.4. 4如果語句s為函數調用語句,則執行第5步,得到新的抽象狀態Stt1,從Succ(S)中選擇某個元素s’,作為s的后繼語句; .4.4. 5如果語句s是函數返回語句return e,則在抽象狀態創下,將指針變量e的擴展類型作為函數返回值的擴展類型,全局指針變量的擴展類型不變,其他局部指針變量的擴展類型賦值置空,得到新的抽象狀態Sb1,并作為函數f的出ロ狀態蝴,,出ロ語句S,作為返回語句s的后繼語句,然后執行4. 5 ; .4.5將新的抽象狀態Stt1與后繼語句s’的初始狀態通過合并操作Join得到該程序點新的抽象狀態免,執行4. 6歩;合并操作是當且僅當任意兩個抽象狀態S〖和S〖存在包括關系時才能合并,否則兩個抽象狀態分別作為合并操作的元素;兩個堆內存抽象狀態Si和S〖存在包含關系S丨g S〖,當且僅當狀態S丨中任意元素在狀態S〖中;合并操作由公式表示為
2.如權利要求1所述的一種面向堆操作程序的內存泄漏檢測方法,其特征在于預處理 中標準形式的指針賦值語句包括7種1),將指針變量p置為空的語句p = null ;2),將指 針變量P的指針域P_ > fm置為空的語句p_ > fm = null ;3),指針變量間拷貝語句p = q ; 4),指針p與指針q的指針域間的拷貝語句P = q_ > fm ;5),指針p的指針域與指針q間的 拷貝語句p_ > fm = q ;6),內存申請語句p = malloc ;7),內存釋放語句free (p)。
3.如權利要求1所述的一種面向堆操作程序的內存泄漏檢測方法,其特征在于所述預 處理中的轉換規則有5種,分別是1),引入輔助指針變量Ph將形如p- > fm = q_ > fn的 指針賦值語句轉換為pt0 = q- > fn ;p- > fm = pt0 ;2),引入輔助指針變量Ph將形如p = P_ > fm的指針賦值語句轉換為ptj = p- > fm ;p = ptj ;3),引入輔助指針變量pt2將形如 p- > fm = malloc的指針賦值語句轉換為pt2 = malloc ;p- > fm = pt2 ;4),引入輔助指 針變量pt3將形如p = q_ > fm_ > fn的指針賦值語句轉換為pt3 = q- > fm ;p = pt3- > fn ;5),引入輔助指針變量pt4將形如free(p- > fm)的內存釋放語句轉換為pt4 = p_ > fm ;free (pt4)。
4.如權利要求1所述的一種面向堆操作程序的內存泄漏檢測方法,其特征在于所述指 針別名集包括全局指針變量、局部指針變量、函數中具有指針類型的形式參數。
全文摘要
本發明公開了一種面向堆操作程序的內存泄漏檢測方法,要解決的技術問題是針對當前堆操作程序內存錯誤檢測方面存在精度和效率的問題,提供一種新的內存泄漏檢測方法,提高檢測的精度和效率。技術方案是先對程序源代碼進行語句分析和詞法分析,生成中間文件;然后進行預處理,包括切片和轉換;接著根據程序中指針變量擴展類型的定義得到堆內存抽象狀態;采用前向數據流迭代方法進行過程內和過程間檢測;最后檢查和統計內存泄漏檢測的結果。本發明在靜態分析的精度和效率間找到了一個較好的平衡點,可加速迭代算法的終止,提高了檢測精度和效率,可擴展性強,存儲開銷少。
文檔編號G06F11/36GK102662825SQ20121004102
公開日2012年9月12日 申請日期2012年2月22日 優先權日2012年2月22日
發明者劉萬偉, 李仁見, 王戟, 董威, 董龍明, 陳立前 申請人:中國人民解放軍國防科學技術大學
網友詢問留言 已有0條留言
  • 還沒有人留言評論。精彩留言會獲得點贊!
1
韩国伦理电影