專利名稱:一種用于vxWorks操作系統(tǒng)檢查內(nèi)存泄漏的方法
技術(shù)領(lǐng)域:
本發(fā)明涉及用于vxWorks操作系統(tǒng)的檢查內(nèi)存泄漏并定位內(nèi)存泄漏處的方法和使 用該方法的軟件。
背景技術(shù):
內(nèi)存管理是計算機科學中的一個重要研究領(lǐng)域,而內(nèi)存管理中的一個重要研究課題 是解決或處理內(nèi)存泄漏(memory leak)問題。所謂內(nèi)存泄漏,是指程序在申請獲得動態(tài) 內(nèi)存并使用完畢后,不釋放動態(tài)內(nèi)存就將保存動態(tài)內(nèi)存地址的變量用于其他用途,使得 這些動態(tài)內(nèi)存不可能再被程序使用,也無法被操作系統(tǒng)回收。內(nèi)存泄漏是軟件開發(fā)中的 最常見最棘手的程序錯誤種類之一。對于規(guī)模較大的程序,內(nèi)存泄漏將導致程序最終因 耗盡系統(tǒng)所有的內(nèi)存,無法再分配到內(nèi)存而崩潰。內(nèi)存泄漏非常不容易查找和定位,使 用常規(guī)的方法很難快速定位內(nèi)存泄漏出現(xiàn)的具體位置,特別是對于vxWorks這種實時操 作系統(tǒng)。vxWorks操作系統(tǒng)一般運行在嵌入式裝置里面,往往很難或不能重啟系統(tǒng),因 此若發(fā)生了內(nèi)存泄漏,常常無法通過靜態(tài)插裝等方式查找內(nèi)存泄漏,而需要實時檢測內(nèi) 存檢泄漏并定位故障,給后一步的補救方案提供依據(jù)。
VxWorks是一個實時操作系統(tǒng)。有以下部件組成內(nèi)核(wind);多任務調(diào)度(采 用基于優(yōu)先級搶占方式,同時支持同優(yōu)先級任務間的分時間片調(diào)度);任務間的同步; 進程間通信機制;中斷處理;定時器和內(nèi)存管理機制;I/O系統(tǒng)。VxWorks提供了一個 快速靈活的與ANSI C兼容的I/O系統(tǒng),包括UNIX標準的Basic I/O。 VxWorks包 括以下驅(qū)動程序網(wǎng)絡驅(qū)動、管道驅(qū)動、RAM盤驅(qū)動、SCSI驅(qū)動、鍵盤驅(qū)動、顯示驅(qū) 動、磁盤驅(qū)動、并口驅(qū)動等。
目前內(nèi)存泄漏監(jiān)測方法一般有兩類,第一類為用靜態(tài)代碼插裝技術(shù),直接修改目標 程序的源代碼,若無源代碼及對應編譯環(huán)境,此工具無法使用。另一類不需要對被測程 序的源代碼進行修改,但必須在目標程序運行之前先運行這些工具,這對于某些運行時 間超長,且無法中斷的程序就無能為力了。
發(fā)明內(nèi)容
本發(fā)明的目的是提供一種用于vxWorks操作系統(tǒng)下查找定位內(nèi)存泄漏的新方法。 本發(fā)明的技術(shù)方案由三部分組成,用于vxWorks操作系統(tǒng)檢査內(nèi)存泄漏的方法, 第一部分,編寫vxWorks系統(tǒng)補丁函數(shù)程序;第二為補丁注入及通信控制程序,第三 部分為內(nèi)存泄漏分析程序,其中第一部分運行在vxWorks里,第二、三部分位于PC機 上。
第一部分,編寫vxWorks系統(tǒng)補丁函數(shù)程序,補丁函數(shù)程序主要是將內(nèi)存申請或 釋放函數(shù)第一條指令替換為跳轉(zhuǎn)指令,此跳轉(zhuǎn)指令第一次跳轉(zhuǎn)到內(nèi)存申請或釋放函數(shù)對 應的補丁函數(shù),此補丁函數(shù)執(zhí)行信息采集程任務,完成信息采集任務后,再跳回到內(nèi)存申請或釋放函數(shù),恢復其運行。內(nèi)存申請或釋放函數(shù)執(zhí)行完后,第二次跳轉(zhuǎn)回補丁函數(shù) 繼續(xù)采集數(shù)據(jù),最后跳回到內(nèi)存申請或釋放函數(shù)調(diào)用者的原始程序流程。從而實現(xiàn)通過 兩次跳轉(zhuǎn)收集申請函數(shù)及釋放函數(shù)的申請地址信息等信息。
第二步,補丁注入及通信控制程序運行在PC機上,通過WTX協(xié)議下載補丁函數(shù) 程序至vxWorks系統(tǒng)中并遠程運行此程序。通過指令覆蓋修改原系統(tǒng)的內(nèi)存申請及釋 放函數(shù)流程,收集補丁函數(shù)程序采集到的內(nèi)存申請函數(shù)和內(nèi)存釋放函數(shù)的信息(如申請 內(nèi)存的大小、申請到的內(nèi)存地址、申請時的相鄰堆棧數(shù)據(jù)等),再通過WTX協(xié)議或套接 字通訊方式上傳這些信息至上位PC機并存儲到PC機中供內(nèi)存泄漏分析程序使用。
第三步,在PC機上通過內(nèi)存泄漏分析程序?qū)崟r分析采集程序收集到的內(nèi)存申請函 數(shù)和內(nèi)存釋放函數(shù)的內(nèi)存地址信息,并進行配對,配對原則是若相鄰的兩接點的內(nèi)存 申請地址、內(nèi)存釋放地址相同,則認為配對成功。配對成功者,刪除這兩條信息,若長 時間(視具體情況而定, 一般半分鐘)未配對成功,則認定此處發(fā)生了內(nèi)存泄漏。再通 過vxWork系統(tǒng)自帶dump工具離線分析目標程序的符號表,查找采集程序收集到的堆 棧數(shù)據(jù)中的返回地址信息在哪個函數(shù)的地址范圍內(nèi),可以確定此內(nèi)存申請函數(shù)被調(diào)用的 具體位置。若源代碼可見的話,甚至可定位到源代碼的具體哪一行出現(xiàn)泄漏。
本發(fā)明的有益效果本發(fā)明提供的方法能夠在不中斷被檢測目標程序運行,不需要 更改目標代碼和不需要補丁先運行的情況下,實時對目標程序進行內(nèi)存泄漏進行檢測并 定位發(fā)生內(nèi)存泄露處。
下面結(jié)合附圖對本發(fā)明的具體實施方式
作進一步詳細的說明。
圖1是一個實施案例的內(nèi)存申請函數(shù)原始指令流程,圖中內(nèi)存申請函數(shù)用malloc 表示,下同。
圖2是一個實施案例打補丁后的內(nèi)存申請函數(shù)指令流程。
圖3是一個實施案例的系統(tǒng)結(jié)構(gòu)圖。
圖4是一個實施案例的補丁函數(shù)程序初始化代碼片段。
圖5是一個實施案例的補丁函數(shù)程序內(nèi)存申請函數(shù)(malloc函數(shù))的補丁函數(shù)的代碼片段。
具體實施例方式
分三部分內(nèi)容
第一部分為編寫vxWorks系統(tǒng)補丁函數(shù)程序。由于vxWorks系統(tǒng)采用平板式內(nèi)存 管理,所有任務(線程)共用同一地址空間,這樣我們就可方便的修改目標任務(程序)的 指令,達到熱補丁目的。補丁函數(shù)程序首先備份內(nèi)存申請函數(shù)(malloc表示,下同)及內(nèi) 存釋放函數(shù)(free表示,下同)的第一條指令到內(nèi)存任意一個位置(全局變量數(shù)組),然后 將原來位置的指令替換為跳轉(zhuǎn)指令,此跳轉(zhuǎn)指令跳轉(zhuǎn)到信息采集程序,信息采集程序收 集完特定信息(下面有詳細描述)后,再跳轉(zhuǎn)到剛才備份的那條指令,執(zhí)行完此指令后,再跳轉(zhuǎn)到原函數(shù)第二條指令,恢復原函數(shù)運行。具體流程如圖1和圖2所示。
vxWorks操作系統(tǒng)內(nèi)的某函數(shù)(用函數(shù)A表示,下同)調(diào)用malloc函數(shù)原始指令 流程如圖1所示。函數(shù)A調(diào)用malloc函數(shù)指令過程為先將malloc函數(shù)的調(diào)用參數(shù)(即 待申請地址大小)及調(diào)用處指令地址(malloc函數(shù)調(diào)用完后返回到函數(shù)A中的指令到地址) 壓棧,然后跳到malloc函數(shù)入口,并開始順序執(zhí)行malloc函數(shù)指令I(lǐng)nstructionA、 InstmctionB等指令,malloc函數(shù)指令執(zhí)行完后就直接回到函數(shù)A繼續(xù)執(zhí)行后續(xù)指令。 圖2為系統(tǒng)打補丁后函數(shù)A調(diào)用malloc函數(shù)指令過程。當函數(shù)A調(diào)用malloc函數(shù)跳 到malloc函數(shù)入口后,首先執(zhí)行跳轉(zhuǎn)指令,跳至補丁函數(shù)FunC.。補丁函數(shù)FunC進 行一部分信息收集工作,例如申請地址大小、堆棧數(shù)據(jù)(包括函數(shù)調(diào)用返回地址)等。然 后執(zhí)行原malloc函數(shù)的第一條指令I(lǐng)nstructionA,然后通過跳轉(zhuǎn)指令跳回原malloc函 數(shù),繼續(xù)執(zhí)行malloc函數(shù)的第二條指令及后續(xù)指令。執(zhí)行完mallloc函數(shù)指令后就再次 返回到補丁函數(shù)FunC中,收集另一部分信息,例如申請到的內(nèi)存地址等,收集完信息 后最終跳回到函數(shù)A,執(zhí)行其后續(xù)指令。
與malloc函數(shù)類似,vxWorks操作系統(tǒng)的函數(shù)A調(diào)用free函數(shù)原始指令流程為 先將調(diào)用參數(shù)(釋放地址)及調(diào)用處地址壓棧,然后跳到free函數(shù)入口,并開始順序執(zhí)行 free函數(shù)指令lnstmctionA、 InstmctionB等指令。執(zhí)行完free函數(shù)后返回函數(shù)A。與 malloc函數(shù)類似,系統(tǒng)打補丁后函數(shù)A調(diào)用free函數(shù)指令過程為當函數(shù)A調(diào)用free 函數(shù)跳到free函數(shù)入口后,首先執(zhí)行跳轉(zhuǎn)指令,瑕fe至補丁函數(shù)FunC,補丁函數(shù)FunC 進行信息收集工作,例如free的地址、堆棧數(shù)據(jù)(包括函數(shù)調(diào)用返回地址)等,然后執(zhí)行 原free函數(shù)的第一條指令I(lǐng)nstructionA,然后通過跳轉(zhuǎn)指令跳回原free函數(shù),繼續(xù)執(zhí)行 free函數(shù)的第二條指令及后續(xù)指令;執(zhí)行完free函數(shù)后就可以返回函數(shù)A,繼續(xù)執(zhí)行free 函數(shù)后面的指令。malloc函數(shù)分配長度為num_bytes字節(jié)的內(nèi)存塊;如果分配成功 則返回指向被分配內(nèi)存的指針,否則返回空指針NULL。當內(nèi)存不再使用時,應使用free() 函數(shù)將內(nèi)存塊釋放。malloc函數(shù)有一個將可用的內(nèi)存塊連接為一個長長的列表的所謂空 閑鏈表。調(diào)用malloc函數(shù)時,它沿連接表尋找一個大到足以滿足用戶請求所需要的內(nèi) 存塊。然后,將該內(nèi)存塊一分為二 (一塊的大小與用戶請求的大小相等,另一塊的大小 就是剩下的字節(jié))。接下來,將分配給用戶的那塊內(nèi)存?zhèn)鹘o用戶,并將剩下的那塊(如 果有的話)返回到連接表上。調(diào)用free函數(shù)時,它將用戶釋放的內(nèi)存塊連接到空閑鏈上。
第二部分通過PC機軟件下載補丁函數(shù)程序。因為所有vxWorks均支持WTX協(xié) 議,WTX協(xié)議支持模塊動態(tài)下載及模塊遠程執(zhí)行,所以PC機軟件通過WTX協(xié)議下載 補丁函數(shù)程序至vxWorks系統(tǒng)中,并遠程運行此程序,如圖5所示。PC機軟件實時收 集補丁函數(shù)程序信息可以通過WTX協(xié)議或套接字通訊方式,這起決于補丁函數(shù)程序上 送信息采用的通信方式。 一般來說采用WTX協(xié)議上傳數(shù)據(jù)效率相對套接字低一些,但 接口簡單,可以與下載模塊接口統(tǒng)一;如果采用套接字方式可以提高效率,但相對而言 編程復雜。因此為了實時性對動態(tài)內(nèi)存申請不太頻繁的系統(tǒng)可以采用WTX協(xié)議,而對動態(tài)內(nèi)存申請很頻繁的系統(tǒng)采用套接字方式較合適。同時為了提高實時性,可以調(diào)高補 丁函數(shù)程序的任務級別。實時收集補丁函數(shù)程序采集到的內(nèi)存申請釋放函數(shù)的信息(如 申請內(nèi)存的大小、申請到的內(nèi)存地址、申請時的相鄰堆棧數(shù)據(jù)等),形成鏈表存儲到PC 機中供內(nèi)存泄漏分析程序使用。
第三部分內(nèi)存泄漏分析程序分析并定位內(nèi)存泄漏。內(nèi)存泄漏分析程序?qū)崟r分析采 集程序收集到的鏈表數(shù)據(jù),并進行鏈表結(jié)點數(shù)據(jù)配對。配對原理是若相鄰的兩接點的
malloc申請地址、free釋放地址相同,則認為配對成功,此次動態(tài)申請內(nèi)存無泄漏,并 從鏈表中刪除這兩個節(jié)點。刪除所有配對成功的節(jié)點后對于剩下的始終未配對成功的節(jié) 點,若此節(jié)點為malloc數(shù)據(jù)節(jié)點,若半分鐘內(nèi)未配對成功,則認定此處發(fā)生了內(nèi)存泄 漏。再通過dump工具分析原vxWork程序的符號表,對比發(fā)生內(nèi)存泄露的節(jié)點的堆棧 數(shù)據(jù)中的返回地址信息,確定此malloc函數(shù)被調(diào)用的位于哪個函數(shù)內(nèi)。若源代碼可見 的話,再根據(jù)malloc函數(shù)申請內(nèi)存的大小,可定位到源代碼的具體哪一行出現(xiàn)泄漏。
以下以ARM處理器vxWorks系統(tǒng)的malloc函數(shù)來具體說明補丁函數(shù)程序流程。 圖4為補丁函數(shù)程序的初始化代碼片段,全局變量Jmp數(shù)組存有兩條指令,指令1為 malloc函數(shù)第一條指令備份的指令,指令2為跳轉(zhuǎn)回malloc函數(shù)第二條指令的指令。 在補丁函數(shù)程序開始運行時,如行9代碼所示,備份malloc函數(shù)第一條指令至Jmp數(shù) 組的指令1。接著如行18代碼所示,將malloc函數(shù)第一條指令修改為跳轉(zhuǎn)至補丁函數(shù) malloc—pre處。最后如行31代碼所示,設置Jmp數(shù)組指令2為從Jmp數(shù)組跳回malloc 函數(shù)第二條指令的指令2。注行18的跳轉(zhuǎn)至指令為補丁流程第一次跳轉(zhuǎn)至補丁函數(shù)。
圖5為malloc補丁函數(shù)代碼片段。在malloc補丁函數(shù)里,行77至行80的代碼用 于收集返回指令地執(zhí)行信息。行90代碼用于保存Jmp數(shù)組的地址。行92代碼設置 malloc函數(shù)值執(zhí)行完后返回的指令地址即malloc函數(shù)值執(zhí)行完后直接返回到行95。行 93代碼用于由補丁函數(shù)跳轉(zhuǎn)至Jmp數(shù)組地址。Jmp數(shù)組兩指令執(zhí)行完后回到malloc 函數(shù)執(zhí)行其第二條指令及其后續(xù)指令。函數(shù)malloc函數(shù)所有指令執(zhí)行完后,再次跳轉(zhuǎn) 至補丁函數(shù)內(nèi),即行95處。跳回補丁函數(shù)后,補丁函數(shù)行98以后的代碼用于再次收集 數(shù)據(jù)并上傳。補丁函數(shù)執(zhí)行完所有指令后,返回到原始調(diào)用函數(shù)FuncA。至此補丁過程 結(jié)束。注行95為補丁流程第二次跳轉(zhuǎn)至補丁函數(shù)。
利用上述方法開發(fā)的vxWorks內(nèi)存泄露檢測軟件在對南瑞繼保電氣公司的 RCS-9798裝置使用后,發(fā)現(xiàn)了 RCS-9798軟件隱含的內(nèi)存泄露問題,并快速定位到了 發(fā)生內(nèi)存泄露的源代碼位置,取得了良好的效果。
權(quán)利要求
1、一種用于vxWorks操作系統(tǒng)檢查內(nèi)存泄漏的方法,其特征是(1)編寫vxVorks系統(tǒng)的內(nèi)存申請函數(shù)和內(nèi)存釋放函數(shù)的跳轉(zhuǎn)指令及其補丁函數(shù)程序;補丁函數(shù)程序?qū)?nèi)存申請函數(shù)和內(nèi)存釋放函數(shù)第一條指令替換為跳轉(zhuǎn)指令,此跳轉(zhuǎn)指令跳轉(zhuǎn)到內(nèi)存申請或釋放函數(shù)對應的補丁函數(shù)程序,此補丁函數(shù)程序執(zhí)行信息采集程任務,完成信息采集任務后,再跳回到內(nèi)存申請或釋放函數(shù),恢復其運行;(2)補丁注入及通信控制程序運行在PC機上,通過WTX協(xié)議下載補丁函數(shù)程序至vxWorks系統(tǒng)中并遠程運行此程序,通過指令覆蓋修改原系統(tǒng)的內(nèi)存申請及釋放函數(shù)流程,收集內(nèi)存申請及內(nèi)存釋放函數(shù)的信息,然后再通過WTX協(xié)議或套接字通信方式實時上傳這些信息至上位PC機中供內(nèi)存泄漏分析程序使用;(3)在PC機上通過內(nèi)存泄漏分析程序?qū)崟r分析采集程序收集到的內(nèi)存申請函數(shù)和內(nèi)存釋放函數(shù)的內(nèi)存地址信息,并進行配對,配對原則是若相鄰的兩接點的內(nèi)存申請地址、內(nèi)存釋放地址相同,則認為配對成功;配對成功者,刪除這兩條信息,若長時間(視具體情況而定,一般半分鐘)未配對成功,則認定此處發(fā)生了內(nèi)存泄漏。再通過vxWork系統(tǒng)自帶dump工具離線分析目標程序的符號表,查找采集程序收集到的堆棧數(shù)據(jù)中的返回地址信息在哪個函數(shù)的地址范圍內(nèi),確定此內(nèi)存申請函數(shù)被調(diào)用的具體位置,從而定位內(nèi)存泄漏發(fā)生處。
2、 由權(quán)利要求1所述的用于vxWorks操作系統(tǒng)檢查內(nèi)存泄漏的方法,其特征是在步 驟(1)完成后,即內(nèi)存申請或釋放函數(shù)執(zhí)行完后,再次跳轉(zhuǎn)回補丁函數(shù)繼續(xù)采集數(shù)據(jù),最后跳回到內(nèi)存申請或釋放函數(shù)調(diào)用者的原始程序流程;即由補丁函數(shù)程序修改內(nèi)存申請函數(shù)、內(nèi)存釋放函數(shù)的指令流程,通過兩次跳轉(zhuǎn)收集申請函數(shù)及釋放函 數(shù)的申請地址信息等信息。
3、 由權(quán)利要求1所述用于vxWorks操作系統(tǒng)檢查內(nèi)存泄漏的方法,其特征是:步驟(3) 中,通過分析原vxWorks程序的函數(shù)符號表,査找發(fā)生內(nèi)存泄露的節(jié)點的堆棧數(shù)據(jù) 中返回地址信息在哪個函數(shù)的地址范圍內(nèi),從而確定調(diào)用該內(nèi)存申請函數(shù)的具體函 數(shù)。
4、 由權(quán)利要求1所述用于vxWorks操作系統(tǒng)檢查內(nèi)存泄漏的方法,其特征是補丁函 數(shù)程序首先備份內(nèi)存申請函數(shù)及內(nèi)存釋放函數(shù)的第一條指令到系統(tǒng)內(nèi)存里任意一個 位置,然后將原來位置的指令替換為跳轉(zhuǎn)指令,此跳轉(zhuǎn)指令跳轉(zhuǎn)到信息采集程序, 信息采集程序收集完特定信息后,再跳轉(zhuǎn)到剛才備份的那條指令處,執(zhí)行完此指令 后,再跳轉(zhuǎn)到原函數(shù)第二條指令,恢復原函數(shù)運行。
全文摘要
本發(fā)明公開了一種用于vxWorks操作系統(tǒng)檢查內(nèi)存泄漏的方法編寫vxVorks系統(tǒng)的內(nèi)存申請函數(shù)和內(nèi)存釋放函數(shù)的跳轉(zhuǎn)指令及其補丁函數(shù)程序;補丁函數(shù)程序?qū)?nèi)存申請函數(shù)和內(nèi)存釋放函數(shù)第一條指令替換為跳轉(zhuǎn)指令,此跳轉(zhuǎn)指令跳轉(zhuǎn)到內(nèi)存申請或釋放函數(shù)對應的補丁函數(shù)程序;補丁注入及通信控制程序運行在PC機上,通過WTX協(xié)議下載補丁函數(shù)程序至vxWorks系統(tǒng)中并遠程運行此程序;在PC機上通過內(nèi)存泄漏分析程序?qū)崟r分析采集程序收集到的內(nèi)存申請函數(shù)和內(nèi)存釋放函數(shù)的內(nèi)存地址信息,并進行配對,若長時間未配對成功,則認定此處發(fā)生了內(nèi)存泄漏。再通過vxWork系統(tǒng)自帶dump工具離線分析定位內(nèi)存泄漏發(fā)生處。
文檔編號G06F11/36GK101587455SQ20081024467
公開日2009年11月25日 申請日期2008年12月11日 優(yōu)先權(quán)日2008年12月11日
發(fā)明者李忠安, 王言國, 胡紹謙 申請人:南京南瑞繼保電氣有限公司;南京南瑞繼保工程技術(shù)有限公司