本發(fā)明涉及計(jì)算機(jī)技術(shù)領(lǐng)域,特別涉及一種確定內(nèi)存泄露位置的方法和裝置。
背景技術(shù):
對(duì)于事先不知需要申請(qǐng)多大內(nèi)存空間的應(yīng)用程序,將會(huì)在運(yùn)行時(shí)動(dòng)態(tài)申請(qǐng)內(nèi)存,當(dāng)使用完畢后,應(yīng)該將動(dòng)態(tài)申請(qǐng)的內(nèi)存釋放掉,若沒(méi)有進(jìn)行釋放,將會(huì)導(dǎo)致內(nèi)存泄漏,即應(yīng)用程序動(dòng)態(tài)申請(qǐng)內(nèi)存,在該內(nèi)存使用完畢后沒(méi)有及時(shí)進(jìn)行釋放,導(dǎo)致該內(nèi)存一直被占用。
技術(shù)人員可以對(duì)應(yīng)用程序進(jìn)行檢測(cè)?,F(xiàn)有技術(shù)中檢測(cè)應(yīng)用程序是否存在內(nèi)存泄露的方法是,在應(yīng)用程序運(yùn)行過(guò)程中,記錄調(diào)用動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù)的函數(shù),例如,當(dāng)a函數(shù)調(diào)用了動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù)時(shí),應(yīng)用程序?qū)?huì)記錄a函數(shù)及其對(duì)應(yīng)的申請(qǐng)到的內(nèi)存。當(dāng)應(yīng)用程序?qū)ι暾?qǐng)到的某內(nèi)存進(jìn)行釋放后,可以將相應(yīng)的記錄刪除。應(yīng)用程序的當(dāng)前流程運(yùn)行結(jié)束后,技術(shù)人員可以在剩余記錄中的函數(shù),找到某個(gè)目標(biāo)函數(shù)出現(xiàn)的所有位置,進(jìn)而基于每個(gè)位置查找相應(yīng)的內(nèi)存釋放語(yǔ)句,最終確定導(dǎo)致內(nèi)存泄露的代碼位置。
在實(shí)現(xiàn)本發(fā)明的過(guò)程中,發(fā)明人發(fā)現(xiàn)現(xiàn)有技術(shù)至少存在以下問(wèn)題:
基于上述處理方式,記錄的函數(shù)可能在整個(gè)程序中多次出現(xiàn),技術(shù)人員需要對(duì)很多個(gè)代碼位置進(jìn)行查找,從而,查找內(nèi)存泄露的代碼位置的效率較低。
技術(shù)實(shí)現(xiàn)要素:
為了解決現(xiàn)有技術(shù)的問(wèn)題,本發(fā)明實(shí)施例提供了一種確定內(nèi)存泄露位置的方法和裝置。所述技術(shù)方案如下:
第一方面,提供了一種確定內(nèi)存泄露位置的方法,所述方法包括:
在目標(biāo)程序執(zhí)行過(guò)程中,當(dāng)檢測(cè)到動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù)被調(diào)用時(shí),獲取通過(guò)所述動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù)申請(qǐng)到的內(nèi)存地址,并獲取所述動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù)當(dāng)前 的各上級(jí)調(diào)用函數(shù)的調(diào)用關(guān)系,在內(nèi)存占用數(shù)據(jù)庫(kù)中,記錄所述內(nèi)存地址與所述調(diào)用關(guān)系的對(duì)應(yīng)關(guān)系;
根據(jù)記錄的調(diào)用關(guān)系,確定發(fā)生內(nèi)存泄露的位置。
在目標(biāo)程序執(zhí)行過(guò)程中,每當(dāng)檢測(cè)到動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù)被調(diào)用時(shí),可以根據(jù)函數(shù)的參數(shù)值申請(qǐng)指定大小的內(nèi)存,并且該函數(shù)可以返回申請(qǐng)到的內(nèi)存的首地址(可以稱為內(nèi)存地址),可以獲取通過(guò)動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù)申請(qǐng)到的內(nèi)存地址,并可以獲取調(diào)用該動(dòng)態(tài)申請(qǐng)函數(shù)的各函數(shù)嵌套關(guān)系,即可以獲取動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù)當(dāng)前的各上級(jí)調(diào)用函數(shù)的調(diào)用關(guān)系,并對(duì)其進(jìn)行存儲(chǔ),獲取內(nèi)存地址以及上述調(diào)用關(guān)系后,可以記錄之間的對(duì)應(yīng)關(guān)系,并存儲(chǔ)在內(nèi)存占用數(shù)據(jù)庫(kù)中,其中,該內(nèi)存占用數(shù)據(jù)庫(kù)可以是內(nèi)存占用表,也可以是內(nèi)存占用樹(shù),即可以將內(nèi)存地址與上述調(diào)用關(guān)系的對(duì)應(yīng)關(guān)系存儲(chǔ)在表中,也可以存儲(chǔ)在樹(shù)中,比如可以是紅黑樹(shù)。其中,動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù)可以用于動(dòng)態(tài)申請(qǐng)系統(tǒng)中的內(nèi)存。在目標(biāo)程序執(zhí)行過(guò)程中,每獲取到動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù)當(dāng)前的各上級(jí)調(diào)用函數(shù)的調(diào)用關(guān)系時(shí),可以存儲(chǔ)調(diào)用關(guān)系對(duì)應(yīng)的內(nèi)存申請(qǐng)次數(shù)和內(nèi)存釋放次數(shù)。獲取到內(nèi)存地址對(duì)應(yīng)的調(diào)用關(guān)系后,可以根據(jù)記錄的調(diào)用關(guān)系,確定發(fā)生內(nèi)存泄露的位置,具體的,計(jì)算設(shè)備還可以在獲取到通過(guò)動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù)申請(qǐng)到的內(nèi)存地址后,獲取該內(nèi)存地址對(duì)應(yīng)的申請(qǐng)時(shí)間點(diǎn),此種情況下,可以確定申請(qǐng)時(shí)間點(diǎn)距離當(dāng)前時(shí)間點(diǎn)的時(shí)長(zhǎng)大于預(yù)設(shè)時(shí)長(zhǎng)的內(nèi)存地址,并確定該內(nèi)存地址對(duì)應(yīng)的調(diào)用關(guān)系,進(jìn)而,可以根據(jù)確定出的申請(qǐng)時(shí)間點(diǎn)距離當(dāng)前時(shí)間點(diǎn)的時(shí)長(zhǎng)大于預(yù)設(shè)時(shí)長(zhǎng)的內(nèi)存地址對(duì)應(yīng)的調(diào)用關(guān)系,確定發(fā)生內(nèi)存泄露的位置。
結(jié)合第一方面,在該第一方面的第一種可能實(shí)現(xiàn)方式中,還包括:
當(dāng)檢測(cè)到動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù)被調(diào)用時(shí),獲取調(diào)用所述動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù)的代碼行標(biāo)識(shí);
所述在內(nèi)存占用數(shù)據(jù)庫(kù)中,記錄所述內(nèi)存地址與所述調(diào)用關(guān)系的對(duì)應(yīng)關(guān)系,包括:
在內(nèi)存占用數(shù)據(jù)庫(kù)中,記錄所述內(nèi)存地址與所述代碼行標(biāo)識(shí)、所述調(diào)用關(guān)系的對(duì)應(yīng)關(guān)系。
在目標(biāo)程序的執(zhí)行過(guò)程中,當(dāng)檢測(cè)到動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù)被調(diào)用時(shí),還可以獲取調(diào)用動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù)的指令地址,進(jìn)而,可以根據(jù)指令地址與代碼位置的對(duì)應(yīng)關(guān)系,確定動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù)在調(diào)用動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù)中的代碼位置, 即檢測(cè)到動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù)被調(diào)用時(shí),獲取調(diào)用動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù)的代碼行標(biāo)識(shí),其中,代碼行標(biāo)識(shí)可以是代碼在調(diào)用函數(shù)中的行號(hào)。此種情況下,可以在內(nèi)存占用數(shù)據(jù)庫(kù)中,記錄內(nèi)存地址與代碼行標(biāo)識(shí)、調(diào)用關(guān)系的對(duì)應(yīng)關(guān)系。
這樣,通過(guò)記錄的調(diào)用關(guān)系以及代碼行標(biāo)識(shí),可以縮小查找的范圍,在目標(biāo)程序中快速找到發(fā)生內(nèi)存泄露的代碼位置。
結(jié)合第一方面或第一方面的第一種可能的實(shí)現(xiàn)方式,在該第一方面的第二種可能實(shí)現(xiàn)方式中,所述獲取所述動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù)當(dāng)前的各上級(jí)調(diào)用函數(shù)的調(diào)用關(guān)系,包括:
獲取所述目標(biāo)程序的棧中當(dāng)前記錄的返回地址,并確定每個(gè)返回地址在所述棧中的排列順序;
根據(jù)所述目標(biāo)程序的指令地址與函數(shù)標(biāo)識(shí)的對(duì)應(yīng)關(guān)系,分別確定與每個(gè)返回地址相同的指令地址所對(duì)應(yīng)的函數(shù)標(biāo)識(shí),得到每個(gè)返回地址對(duì)應(yīng)的函數(shù)標(biāo)識(shí);
根據(jù)所述每個(gè)返回地址在所述棧中的排列順序,以及每個(gè)返回地址對(duì)應(yīng)的函數(shù)標(biāo)識(shí),確定所述動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù)當(dāng)前的各上級(jí)調(diào)用函數(shù)的調(diào)用關(guān)系。
在運(yùn)行目標(biāo)程序中的函數(shù)時(shí),會(huì)將函數(shù)的相關(guān)信息壓進(jìn)目標(biāo)程序的棧中,其中,函數(shù)的相關(guān)信息可以是函數(shù)對(duì)應(yīng)的返回地址(運(yùn)行某函數(shù)時(shí),函數(shù)的返回地址最先進(jìn)棧)、函數(shù)涉及的局部變量、函數(shù)的參數(shù)值,也就是說(shuō),該函數(shù)的相關(guān)信息會(huì)占用棧的某一段空間。函數(shù)被壓進(jìn)棧后,可以通過(guò)當(dāng)前的棧幀地址獲取該函數(shù)所在棧中的首地址,其中,棧幀地址可以是該函數(shù)對(duì)應(yīng)的相關(guān)信息占用的棧的某一段空間的首地址。當(dāng)該函數(shù)運(yùn)行結(jié)束后,該函數(shù)對(duì)應(yīng)的相關(guān)信息即會(huì)出棧。從而,可以獲取目標(biāo)程序的棧中當(dāng)前記錄的返回地址,并確定每個(gè)返回地址在棧中的排列順序。獲取目標(biāo)程序的棧中當(dāng)前記錄的返回地址后,可以獲取本地存儲(chǔ)的目標(biāo)程序的指令地址與函數(shù)標(biāo)識(shí)的對(duì)應(yīng)關(guān)系,即指令地址對(duì)應(yīng)的代碼所屬的函數(shù)的對(duì)應(yīng)關(guān)系,并可以在目標(biāo)程序的指令地址與函數(shù)標(biāo)識(shí)的對(duì)應(yīng)關(guān)系中,獲取與返回地址相同的指令地址所對(duì)應(yīng)的函數(shù)標(biāo)識(shí),其中,被調(diào)用函數(shù)的返回地址即是調(diào)用函數(shù)的指令地址,得到每個(gè)返回地址對(duì)應(yīng)的函數(shù)標(biāo)識(shí)。得到每個(gè)返回地址對(duì)應(yīng)的函數(shù)標(biāo)識(shí)后,可以根據(jù)獲取的每個(gè)返回地址在棧中的排列順序,以及每個(gè)返回地址對(duì)應(yīng)的函數(shù)標(biāo)識(shí),確定動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù)當(dāng)前的各上級(jí)調(diào)用函數(shù)的調(diào)用關(guān)系。由于調(diào)用函數(shù)先入棧,被調(diào)用的函數(shù)后入棧,從而,可以根據(jù)獲取的每個(gè)返回地址在棧中的排列順序獲知函數(shù)的調(diào)用關(guān) 系。
結(jié)合第一方面的第二種可能實(shí)現(xiàn)方式,在該第一方面的第三種可能實(shí)現(xiàn)方式中,所述得到每個(gè)返回地址對(duì)應(yīng)的函數(shù)標(biāo)識(shí)之后還包括:
在每個(gè)返回地址對(duì)應(yīng)的函數(shù)標(biāo)識(shí)中,確定滿足預(yù)設(shè)過(guò)濾條件的函數(shù)標(biāo)識(shí),選取所述滿足預(yù)設(shè)過(guò)濾條件的函數(shù)標(biāo)識(shí)對(duì)應(yīng)的返回地址;
所述根據(jù)所述每個(gè)返回地址在所述棧中的排列順序,以及每個(gè)返回地址對(duì)應(yīng)的函數(shù)標(biāo)識(shí),確定所述動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù)當(dāng)前的各上級(jí)調(diào)用函數(shù)的調(diào)用關(guān)系,包括:
根據(jù)選取的返回地址在所述棧中的排列順序,以及所述滿足預(yù)設(shè)過(guò)濾條件的函數(shù)標(biāo)識(shí),確定所述動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù)當(dāng)前的各上級(jí)調(diào)用函數(shù)的調(diào)用關(guān)系。
可以預(yù)先設(shè)置過(guò)濾條件(可以稱為預(yù)設(shè)過(guò)濾條件)并存儲(chǔ),其中,可以通過(guò)預(yù)設(shè)過(guò)濾條件將c標(biāo)準(zhǔn)函數(shù)或者已經(jīng)確定不會(huì)發(fā)生內(nèi)存泄露的函數(shù)過(guò)濾掉。得到目標(biāo)程序的棧中當(dāng)前記錄的返回地址對(duì)應(yīng)的函數(shù)標(biāo)識(shí)后,可以判斷對(duì)應(yīng)的函數(shù)標(biāo)識(shí)是否滿足預(yù)設(shè)過(guò)濾條件,可以在獲取的所有的函數(shù)標(biāo)識(shí)中選取滿足預(yù)設(shè)過(guò)濾條件的函數(shù)標(biāo)識(shí),進(jìn)而可以根據(jù)得到的每個(gè)返回地址與函數(shù)標(biāo)識(shí)的對(duì)應(yīng)關(guān)系,選取滿足預(yù)設(shè)過(guò)濾條件的函數(shù)標(biāo)識(shí)對(duì)應(yīng)的返回地址。過(guò)濾掉一般部分函數(shù)標(biāo)識(shí)后,可以根據(jù)剩余的返回地址在棧中的排列順序,以及剩余的返回地址對(duì)應(yīng)的函數(shù)標(biāo)識(shí),確定動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù)當(dāng)前的各上級(jí)調(diào)用函數(shù)的調(diào)用關(guān)系。
這樣,存儲(chǔ)的信息相對(duì)來(lái)講將會(huì)減少,從而,可以節(jié)約存儲(chǔ)空間,以及可以提高確定發(fā)生內(nèi)存泄露的位置的效率。
結(jié)合第一方面,在該第一方面的第四種可能實(shí)現(xiàn)方式中,還包括:
當(dāng)檢測(cè)到所述內(nèi)存地址對(duì)應(yīng)的內(nèi)存被釋放時(shí),從所述內(nèi)存占用數(shù)據(jù)庫(kù)中刪除所述內(nèi)存地址所屬的對(duì)應(yīng)關(guān)系。
在目標(biāo)程序執(zhí)行過(guò)程中,每當(dāng)檢測(cè)到內(nèi)存釋放函數(shù)被調(diào)用時(shí),其中,內(nèi)存釋放函數(shù)可以用于對(duì)通過(guò)動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù)申請(qǐng)到的內(nèi)存進(jìn)行釋放,即檢測(cè)到內(nèi)存地址對(duì)應(yīng)的內(nèi)存被釋放時(shí),可以從內(nèi)存數(shù)據(jù)庫(kù)中刪除內(nèi)存地址所屬的對(duì)應(yīng)關(guān)系。
結(jié)合第一方面的第四種可能實(shí)現(xiàn)方式,在該第一方面的第五種可能實(shí)現(xiàn)方式中,所述在目標(biāo)程序執(zhí)行過(guò)程中,當(dāng)檢測(cè)到動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù)被調(diào)用時(shí),獲取通過(guò)所述動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù)申請(qǐng)到的內(nèi)存地址,并獲取所述動(dòng)態(tài)內(nèi)存申請(qǐng)函 數(shù)當(dāng)前的各上級(jí)調(diào)用函數(shù)的調(diào)用關(guān)系,在內(nèi)存占用數(shù)據(jù)庫(kù)中,記錄所述內(nèi)存地址與所述調(diào)用關(guān)系的對(duì)應(yīng)關(guān)系,包括:
在目標(biāo)程序執(zhí)行過(guò)程中,當(dāng)檢測(cè)到所述動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù)的調(diào)用指令時(shí),執(zhí)行預(yù)設(shè)動(dòng)態(tài)鏈接庫(kù)中的程序,以執(zhí)行所述動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù),獲取通過(guò)所述動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù)申請(qǐng)到的內(nèi)存地址,并獲取所述調(diào)用指令的各上級(jí)調(diào)用函數(shù)的調(diào)用關(guān)系,在內(nèi)存占用數(shù)據(jù)庫(kù)中,記錄所述內(nèi)存地址與所述調(diào)用關(guān)系的對(duì)應(yīng)關(guān)系;
所述當(dāng)檢測(cè)到所述內(nèi)存地址對(duì)應(yīng)的內(nèi)存被釋放時(shí),從所述內(nèi)存占用數(shù)據(jù)庫(kù)中刪除所述內(nèi)存地址所屬的對(duì)應(yīng)關(guān)系,包括:
當(dāng)檢測(cè)到對(duì)所述內(nèi)存地址對(duì)應(yīng)的內(nèi)存的釋放指令時(shí),執(zhí)行所述預(yù)設(shè)動(dòng)態(tài)鏈接庫(kù)中的程序,釋放所述內(nèi)存,并從所述內(nèi)存占用數(shù)據(jù)庫(kù)中刪除所述內(nèi)存地址所屬的對(duì)應(yīng)關(guān)系。
可以預(yù)先設(shè)置動(dòng)態(tài)鏈接庫(kù)(可以稱為預(yù)設(shè)動(dòng)態(tài)鏈接庫(kù)),在目標(biāo)程序執(zhí)行過(guò)程中,當(dāng)檢測(cè)到動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù)的調(diào)用指令時(shí),可以執(zhí)行預(yù)設(shè)動(dòng)態(tài)鏈接庫(kù)中的程序,以便執(zhí)行動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù),此時(shí),預(yù)設(shè)動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù)中的程序相當(dāng)于是動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù)的具體代碼,當(dāng)預(yù)設(shè)動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù)中的程序全部執(zhí)行完畢時(shí),即相當(dāng)于動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù)執(zhí)行完畢。具體的,執(zhí)行預(yù)設(shè)動(dòng)態(tài)鏈接庫(kù)中的程序,可以獲取通過(guò)動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù)申請(qǐng)到的內(nèi)存地址,并獲取調(diào)用指令的各上級(jí)調(diào)用函數(shù)的調(diào)用關(guān)系,即獲取目標(biāo)程序中調(diào)用動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù)的各上級(jí)調(diào)用函數(shù)的調(diào)用關(guān)系,并可以在內(nèi)存占用數(shù)據(jù)庫(kù)中,記錄內(nèi)存地址與調(diào)用關(guān)系的對(duì)應(yīng)關(guān)系。
針對(duì)刪除內(nèi)存地址所屬的對(duì)應(yīng)關(guān)系的情況,在目標(biāo)程序的執(zhí)行過(guò)程中,當(dāng)檢測(cè)到對(duì)內(nèi)存地址對(duì)應(yīng)的內(nèi)存的釋放指令時(shí),也可以執(zhí)行預(yù)設(shè)動(dòng)態(tài)鏈接庫(kù)中的程序,對(duì)內(nèi)存地址對(duì)應(yīng)的內(nèi)存進(jìn)行釋放,并可以從內(nèi)存占用數(shù)據(jù)庫(kù)中刪除內(nèi)存地址所屬的對(duì)應(yīng)關(guān)系。
這樣,無(wú)需修改目標(biāo)程序,通過(guò)執(zhí)行預(yù)設(shè)動(dòng)態(tài)鏈接庫(kù)中的程序即可獲取目標(biāo)程序通過(guò)動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù)申請(qǐng)到的內(nèi)存地址,以及對(duì)應(yīng)的各上級(jí)調(diào)用函數(shù)的調(diào)用關(guān)系,另外,利用此種方式,若目標(biāo)程序無(wú)法修改時(shí),其中,當(dāng)目標(biāo)程序是標(biāo)準(zhǔn)c函數(shù)或者第三方程序時(shí),技術(shù)人員無(wú)法對(duì)源代碼進(jìn)行修改,也可以通過(guò)執(zhí)行預(yù)設(shè)動(dòng)態(tài)鏈接庫(kù)中的程序獲取相關(guān)的信息,以便進(jìn)行后續(xù)確定發(fā)生內(nèi) 存泄露的位置的相關(guān)處理。
結(jié)合第一方面或第一方面的第一至五種可能實(shí)現(xiàn)方式,在該第一方面的第六種可能實(shí)現(xiàn)方式中,確定每個(gè)調(diào)用關(guān)系對(duì)應(yīng)的內(nèi)存申請(qǐng)次數(shù)和內(nèi)存釋放次數(shù),確定所述每個(gè)調(diào)用關(guān)系對(duì)應(yīng)的內(nèi)存申請(qǐng)次數(shù)和內(nèi)存釋放次數(shù)的差值;
在所述每個(gè)調(diào)用關(guān)系對(duì)應(yīng)的內(nèi)存申請(qǐng)次數(shù)和內(nèi)存釋放次數(shù)的差值中,確定滿足預(yù)設(shè)選取條件的差值,選取滿足預(yù)設(shè)選取條件的差值對(duì)應(yīng)的目標(biāo)調(diào)用關(guān)系;
將所述目標(biāo)調(diào)用關(guān)系對(duì)應(yīng)的程序位置確定為發(fā)生內(nèi)存泄露的位置。
可以預(yù)先設(shè)置差值獲取觸發(fā)事件,其中,差值獲取觸發(fā)事件可以是達(dá)到預(yù)設(shè)的差值獲取周期,也可以是檢測(cè)到存儲(chǔ)內(nèi)存地址與調(diào)用關(guān)系的對(duì)應(yīng)關(guān)系,每當(dāng)檢測(cè)到預(yù)設(shè)的差值獲取觸發(fā)事件發(fā)生時(shí),可以確定已經(jīng)存儲(chǔ)的每個(gè)調(diào)用關(guān)系對(duì)應(yīng)的內(nèi)存申請(qǐng)次數(shù)和內(nèi)存釋放次數(shù),確定每個(gè)調(diào)用關(guān)系對(duì)應(yīng)的內(nèi)存申請(qǐng)次數(shù)和內(nèi)存釋放次數(shù)的差值。之后,可以在每個(gè)調(diào)用關(guān)系對(duì)應(yīng)的內(nèi)存申請(qǐng)次數(shù)和內(nèi)存釋放次數(shù)的差值中,確定滿足預(yù)設(shè)選取條件的差值,并且可以選取滿足預(yù)設(shè)選取條件的差值對(duì)應(yīng)的目標(biāo)調(diào)用關(guān)系,進(jìn)而,可以將目標(biāo)調(diào)用關(guān)系對(duì)應(yīng)的程序位置確定為發(fā)生內(nèi)存泄露的位置,即可以將目標(biāo)程序中出現(xiàn)目標(biāo)調(diào)用關(guān)系的代碼位置確定為發(fā)生內(nèi)存泄露的位置。
結(jié)合第一方面的第六種可能實(shí)現(xiàn)方式,在該第一方面的第七種可能實(shí)現(xiàn)方式中,在所述每個(gè)調(diào)用關(guān)系對(duì)應(yīng)的內(nèi)存申請(qǐng)次數(shù)和內(nèi)存釋放次數(shù)的差值中,獲取預(yù)設(shè)數(shù)目個(gè)最大的差值,并確定所述預(yù)設(shè)數(shù)目個(gè)最大的差值對(duì)應(yīng)的目標(biāo)調(diào)用關(guān)系。
確定出每個(gè)調(diào)用關(guān)系對(duì)應(yīng)的內(nèi)存申請(qǐng)次數(shù)和內(nèi)存釋放次數(shù)的差值后,可以按照差值由大到小的順序,對(duì)其進(jìn)行排序,可以從中獲取排在前列的預(yù)設(shè)數(shù)目個(gè)差值對(duì)應(yīng)的目標(biāo)調(diào)用關(guān)系
這樣,確定出的目標(biāo)調(diào)用關(guān)系是最有可能發(fā)生內(nèi)存泄露的位置,并且可以在目標(biāo)程序的執(zhí)行過(guò)程中,實(shí)時(shí)檢測(cè)發(fā)生內(nèi)存泄露的位置。
第二方面,提供了一種確定內(nèi)存泄露位置的裝置,所述裝置包括處理器、存儲(chǔ)器,其中:
所述處理器,用于在目標(biāo)程序執(zhí)行過(guò)程中,當(dāng)檢測(cè)到動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù)被調(diào)用時(shí),獲取通過(guò)所述動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù)申請(qǐng)到的內(nèi)存地址,并獲取所述動(dòng)態(tài) 內(nèi)存申請(qǐng)函數(shù)當(dāng)前的各上級(jí)調(diào)用函數(shù)的調(diào)用關(guān)系,在所述存儲(chǔ)器中建立的內(nèi)存占用數(shù)據(jù)庫(kù)中,記錄所述內(nèi)存地址與所述調(diào)用關(guān)系的對(duì)應(yīng)關(guān)系;根據(jù)記錄的調(diào)用關(guān)系,確定發(fā)生內(nèi)存泄露的位置。
結(jié)合第二方面,在該第二方面的第一種可能實(shí)現(xiàn)方式中,所述處理器,還用于:
當(dāng)檢測(cè)到動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù)被調(diào)用時(shí),獲取調(diào)用所述動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù)的代碼行標(biāo)識(shí);
所述處理器,具體用于:
在內(nèi)存占用數(shù)據(jù)庫(kù)中,記錄所述內(nèi)存地址與所述代碼行標(biāo)識(shí)、所述調(diào)用關(guān)系的對(duì)應(yīng)關(guān)系。
結(jié)合第二方面或第二方面的第一種可能的實(shí)現(xiàn)方式,在該第二方面的第二種可能實(shí)現(xiàn)方式中,所述處理器,具體用于:
獲取所述目標(biāo)程序的棧中當(dāng)前記錄的返回地址,并確定每個(gè)返回地址在所述棧中的排列順序;
根據(jù)所述目標(biāo)程序的指令地址與函數(shù)標(biāo)識(shí)的對(duì)應(yīng)關(guān)系,分別確定與每個(gè)返回地址相同的指令地址所對(duì)應(yīng)的函數(shù)標(biāo)識(shí),得到每個(gè)返回地址對(duì)應(yīng)的函數(shù)標(biāo)識(shí);
根據(jù)所述每個(gè)返回地址在所述棧中的排列順序,以及每個(gè)返回地址對(duì)應(yīng)的函數(shù)標(biāo)識(shí),確定所述動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù)當(dāng)前的各上級(jí)調(diào)用函數(shù)的調(diào)用關(guān)系。
結(jié)合第二方面的第二種可能實(shí)現(xiàn)方式,在該第二方面的三種可能實(shí)現(xiàn)方式中,所述處理器,還用于:
在每個(gè)返回地址對(duì)應(yīng)的函數(shù)標(biāo)識(shí)中,確定滿足預(yù)設(shè)過(guò)濾條件的函數(shù)標(biāo)識(shí),選取所述滿足預(yù)設(shè)過(guò)濾條件的函數(shù)標(biāo)識(shí)對(duì)應(yīng)的返回地址;
所述處理器,具體用于:
根據(jù)選取的返回地址在所述棧中的排列順序,以及所述滿足預(yù)設(shè)過(guò)濾條件的函數(shù)標(biāo)識(shí),確定所述動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù)當(dāng)前的各上級(jí)調(diào)用函數(shù)的調(diào)用關(guān)系。
結(jié)合第二方面,在該第二方面的第四種可能實(shí)現(xiàn)方式中,所述處理器,還用于:
當(dāng)檢測(cè)到所述內(nèi)存地址對(duì)應(yīng)的內(nèi)存被釋放時(shí),從所述內(nèi)存占用數(shù)據(jù)庫(kù)中刪除所述內(nèi)存地址所屬的對(duì)應(yīng)關(guān)系。
結(jié)合第二方面的第四種可能實(shí)現(xiàn)方式,在該第二方面的第五種可能實(shí)現(xiàn)方 式中,所述處理器,具體用于:
在目標(biāo)程序執(zhí)行過(guò)程中,當(dāng)檢測(cè)到所述動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù)的調(diào)用指令時(shí),執(zhí)行預(yù)設(shè)動(dòng)態(tài)鏈接庫(kù)中的程序,以執(zhí)行所述動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù),獲取通過(guò)所述動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù)申請(qǐng)到的內(nèi)存地址,并獲取所述調(diào)用指令的各上級(jí)調(diào)用函數(shù)的調(diào)用關(guān)系,在內(nèi)存占用數(shù)據(jù)庫(kù)中,記錄所述內(nèi)存地址與所述調(diào)用關(guān)系的對(duì)應(yīng)關(guān)系;
當(dāng)檢測(cè)到對(duì)所述內(nèi)存地址對(duì)應(yīng)的內(nèi)存的釋放指令時(shí),執(zhí)行所述預(yù)設(shè)動(dòng)態(tài)鏈接庫(kù)中的程序,釋放所述內(nèi)存,并從所述內(nèi)存占用數(shù)據(jù)庫(kù)中刪除所述內(nèi)存地址所屬的對(duì)應(yīng)關(guān)系。
結(jié)合第二方面或者第二方面的第一至五種可能實(shí)現(xiàn)方式,在該第二方面的第六種可能實(shí)現(xiàn)方式中,所述處理器,具體用于:
確定每個(gè)調(diào)用關(guān)系對(duì)應(yīng)的內(nèi)存申請(qǐng)次數(shù)和內(nèi)存釋放次數(shù),確定所述每個(gè)調(diào)用關(guān)系對(duì)應(yīng)的內(nèi)存申請(qǐng)次數(shù)和內(nèi)存釋放次數(shù)的差值;
在所述每個(gè)調(diào)用關(guān)系對(duì)應(yīng)的內(nèi)存申請(qǐng)次數(shù)和內(nèi)存釋放次數(shù)的差值中,確定滿足預(yù)設(shè)選取條件的差值,選取滿足預(yù)設(shè)選取條件的差值對(duì)應(yīng)的目標(biāo)調(diào)用關(guān)系;
將所述目標(biāo)調(diào)用關(guān)系對(duì)應(yīng)的程序位置確定為發(fā)生內(nèi)存泄露的位置。
結(jié)合第二方面的第六種可能實(shí)現(xiàn)方式,在該第二方面的第七種可能實(shí)現(xiàn)方式中,所述處理器,具體用于:
在所述每個(gè)調(diào)用關(guān)系對(duì)應(yīng)的內(nèi)存申請(qǐng)次數(shù)和內(nèi)存釋放次數(shù)的差值中,獲取預(yù)設(shè)數(shù)目個(gè)最大的差值,并確定所述預(yù)設(shè)數(shù)目個(gè)最大的差值對(duì)應(yīng)的目標(biāo)調(diào)用關(guān)系。
第三方面,提供了一種確定內(nèi)存泄露位置的裝置,包括:
獲取模塊,具體可以由處理器實(shí)現(xiàn),用于在目標(biāo)程序執(zhí)行過(guò)程中,當(dāng)檢測(cè)到動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù)被調(diào)用時(shí),獲取通過(guò)所述動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù)申請(qǐng)到的內(nèi)存地址,并獲取所述動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù)當(dāng)前的各上級(jí)調(diào)用函數(shù)的調(diào)用關(guān)系,在內(nèi)存占用數(shù)據(jù)庫(kù)中,記錄所述內(nèi)存地址與所述調(diào)用關(guān)系的對(duì)應(yīng)關(guān)系;
確定模塊,具體可以由處理器實(shí)現(xiàn),用于根據(jù)所述獲取模塊記錄的調(diào)用關(guān)系,確定發(fā)生內(nèi)存泄露的位置。
結(jié)合第三方面,在該第三方面的第一種可能實(shí)現(xiàn)方式中,所述獲取模塊, 還用于:
當(dāng)檢測(cè)到動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù)被調(diào)用時(shí),獲取調(diào)用所述動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù)的代碼行標(biāo)識(shí);
所述獲取模塊,具體用于:
在內(nèi)存占用數(shù)據(jù)庫(kù)中,記錄所述內(nèi)存地址與所述代碼行標(biāo)識(shí)、所述調(diào)用關(guān)系的對(duì)應(yīng)關(guān)系。
結(jié)合第三方面或第三方面的第一種可能的實(shí)現(xiàn)方式,在該第三方面的第二種可能實(shí)現(xiàn)方式中,所述獲取模塊,具體用于:
獲取所述目標(biāo)程序的棧中當(dāng)前記錄的返回地址,并確定每個(gè)返回地址在所述棧中的排列順序;
所述確定模塊,具體用于:
根據(jù)所述目標(biāo)程序的指令地址與函數(shù)標(biāo)識(shí)的對(duì)應(yīng)關(guān)系,分別確定與每個(gè)返回地址相同的指令地址所對(duì)應(yīng)的函數(shù)標(biāo)識(shí),得到每個(gè)返回地址對(duì)應(yīng)的函數(shù)標(biāo)識(shí);
根據(jù)所述每個(gè)返回地址在所述棧中的排列順序,以及每個(gè)返回地址對(duì)應(yīng)的函數(shù)標(biāo)識(shí),確定所述動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù)當(dāng)前的各上級(jí)調(diào)用函數(shù)的調(diào)用關(guān)系。
結(jié)合第三方面的第二種可能實(shí)現(xiàn)方式,在該第三方面的第三種可能實(shí)現(xiàn)方式中,所述確定模塊,還用于:
在每個(gè)返回地址對(duì)應(yīng)的函數(shù)標(biāo)識(shí)中,確定滿足預(yù)設(shè)過(guò)濾條件的函數(shù)標(biāo)識(shí),選取所述滿足預(yù)設(shè)過(guò)濾條件的函數(shù)標(biāo)識(shí)對(duì)應(yīng)的返回地址;
所述確定模塊,具體用于:
根據(jù)選取的返回地址在所述棧中的排列順序,以及所述滿足預(yù)設(shè)過(guò)濾條件的函數(shù)標(biāo)識(shí),確定所述動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù)當(dāng)前的各上級(jí)調(diào)用函數(shù)的調(diào)用關(guān)系。
結(jié)合第三方面,在該第三方面的第四種可能實(shí)現(xiàn)方式中,還包括:
刪除模塊,用于當(dāng)檢測(cè)到所述內(nèi)存地址對(duì)應(yīng)的內(nèi)存被釋放時(shí),從所述內(nèi)存占用數(shù)據(jù)庫(kù)中刪除所述內(nèi)存地址所屬的對(duì)應(yīng)關(guān)系。
結(jié)合第三方面的第四種可能實(shí)現(xiàn)方式,在該第三方面的第五種可能實(shí)現(xiàn)方式中,所述獲取模塊,具體用于:
在目標(biāo)程序執(zhí)行過(guò)程中,當(dāng)檢測(cè)到所述動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù)的調(diào)用指令時(shí),執(zhí)行預(yù)設(shè)動(dòng)態(tài)鏈接庫(kù)中的程序,以執(zhí)行所述動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù),獲取通過(guò)所述動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù)申請(qǐng)到的內(nèi)存地址,并獲取所述調(diào)用指令的各上級(jí)調(diào)用函數(shù) 的調(diào)用關(guān)系,在內(nèi)存占用數(shù)據(jù)庫(kù)中,記錄所述內(nèi)存地址與所述調(diào)用關(guān)系的對(duì)應(yīng)關(guān)系;
所述刪除模塊,具體用于:
當(dāng)檢測(cè)到對(duì)所述內(nèi)存地址對(duì)應(yīng)的內(nèi)存的釋放指令時(shí),執(zhí)行所述預(yù)設(shè)動(dòng)態(tài)鏈接庫(kù)中的程序,釋放所述內(nèi)存,并從所述內(nèi)存占用數(shù)據(jù)庫(kù)中刪除所述內(nèi)存地址所屬的對(duì)應(yīng)關(guān)系。
結(jié)合第三方面或者第三方面的第一至五種可能實(shí)現(xiàn)方式,在該第三方面的第六種可能實(shí)現(xiàn)方式中,所述確定模塊,具體用于:
確定每個(gè)調(diào)用關(guān)系對(duì)應(yīng)的內(nèi)存申請(qǐng)次數(shù)和內(nèi)存釋放次數(shù),確定所述每個(gè)調(diào)用關(guān)系對(duì)應(yīng)的內(nèi)存申請(qǐng)次數(shù)和內(nèi)存釋放次數(shù)的差值;
在所述每個(gè)調(diào)用關(guān)系對(duì)應(yīng)的內(nèi)存申請(qǐng)次數(shù)和內(nèi)存釋放次數(shù)的差值中,確定滿足預(yù)設(shè)選取條件的差值,選取滿足預(yù)設(shè)選取條件的差值對(duì)應(yīng)的目標(biāo)調(diào)用關(guān)系;
將所述目標(biāo)調(diào)用關(guān)系對(duì)應(yīng)的程序位置確定為發(fā)生內(nèi)存泄露的位置。
結(jié)合第三方面的第六種可能實(shí)現(xiàn)方式,在該第三方面的第七種可能實(shí)現(xiàn)方式中,所述確定模塊,具體用于:
在所述每個(gè)調(diào)用關(guān)系對(duì)應(yīng)的內(nèi)存申請(qǐng)次數(shù)和內(nèi)存釋放次數(shù)的差值中,獲取預(yù)設(shè)數(shù)目個(gè)最大的差值,并確定所述預(yù)設(shè)數(shù)目個(gè)最大的差值對(duì)應(yīng)的目標(biāo)調(diào)用關(guān)系。
本發(fā)明實(shí)施例提供的技術(shù)方案帶來(lái)的有益效果是:
本發(fā)明實(shí)施例中,在目標(biāo)程序執(zhí)行過(guò)程中,當(dāng)檢測(cè)到動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù)被調(diào)用時(shí),獲取通過(guò)動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù)申請(qǐng)到的內(nèi)存地址,并獲取動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù)當(dāng)前的各上級(jí)調(diào)用函數(shù)的調(diào)用關(guān)系,在內(nèi)存占用數(shù)據(jù)庫(kù)中,記錄內(nèi)存地址與調(diào)用關(guān)系的對(duì)應(yīng)關(guān)系,根據(jù)記錄的調(diào)用關(guān)系,確定發(fā)生內(nèi)存泄露的位置。這樣,在目標(biāo)程序執(zhí)行過(guò)程中,可以通過(guò)記錄的調(diào)用關(guān)系,縮小查找的范圍,在目標(biāo)程序中快速找到發(fā)生內(nèi)存泄露的代碼位置,從而,可以提高查找內(nèi)存泄露的代碼位置的效率。
附圖說(shuō)明
為了更清楚地說(shuō)明本發(fā)明實(shí)施例中的技術(shù)方案,下面將對(duì)實(shí)施例描述中所需要使用的附圖作簡(jiǎn)單地介紹。
圖1是本發(fā)明實(shí)施例提供的一種計(jì)算設(shè)備的結(jié)構(gòu)示意圖;
圖2是本發(fā)明實(shí)施例提供的一種確定內(nèi)存泄露位置的方法流程圖;
圖3是本發(fā)明實(shí)施例提供的一種獲取調(diào)用關(guān)系的方法流程圖;
圖4是本發(fā)明實(shí)施例提供的一種獲取返回地址的示意圖;
圖5是本發(fā)明實(shí)施例提供的一種確定內(nèi)存泄露位置的裝置結(jié)構(gòu)示意圖;
圖6是本發(fā)明實(shí)施例提供的一種確定內(nèi)存泄露位置的裝置結(jié)構(gòu)示意圖。
具體實(shí)施方式
為使本發(fā)明的目的、技術(shù)方案和優(yōu)點(diǎn)更加清楚,下面將結(jié)合附圖對(duì)本發(fā)明實(shí)施方式作進(jìn)一步地詳細(xì)描述。
本發(fā)明實(shí)施例提供了一種確定內(nèi)存泄露位置的方法,該方法的執(zhí)行主體為計(jì)算設(shè)備。其中,計(jì)算設(shè)備可以是個(gè)人計(jì)算機(jī)(personalcomputer,pc),也可以是服務(wù)器。
計(jì)算設(shè)備可以包括處理器110、存儲(chǔ)器120,處理器110可以與存儲(chǔ)器120進(jìn)行連接,如圖1所示。處理器110可以是計(jì)算設(shè)備的控制中心,利用各種接口和線路連接計(jì)算設(shè)備的各個(gè)部分,通過(guò)運(yùn)行或執(zhí)行存儲(chǔ)在存儲(chǔ)器120內(nèi)的軟件程序和/或模塊,以及調(diào)用存儲(chǔ)在存儲(chǔ)器120內(nèi)的數(shù)據(jù),執(zhí)行計(jì)算設(shè)備的各種功能和處理數(shù)據(jù),從而對(duì)計(jì)算設(shè)備進(jìn)行整體監(jiān)控。處理器110可以包括一個(gè)或多個(gè)處理單元;處理器110可以是通用處理器,包括中央處理器(centralprocessingunit,簡(jiǎn)稱cpu)、網(wǎng)絡(luò)處理器(networkprocessor,簡(jiǎn)稱np)等;還可以是數(shù)字信號(hào)處理器(dsp)、專用集成電路(asic)、現(xiàn)場(chǎng)可編程門陣列(fpga)或者其他可編程邏輯器件等。存儲(chǔ)器110可以用于存儲(chǔ)程序。具體地,程序可以包括程序代碼,程序代碼包括計(jì)算機(jī)操作指令。存儲(chǔ)器120可能包含ram,也可能還包括非易失性存儲(chǔ)器(non-volatilememory),例如至少一個(gè)磁盤存儲(chǔ)器。處理器110執(zhí)行存儲(chǔ)器120中存儲(chǔ)的程序代碼,以實(shí)現(xiàn)各種功能,其中,本發(fā)明中,存儲(chǔ)器還可以用于存儲(chǔ)下述處理過(guò)程中需要和產(chǎn)生的數(shù)據(jù)。
如圖2所示,該方法的具體處理流程可以包括如下的步驟:
步驟201,在目標(biāo)程序執(zhí)行過(guò)程中,當(dāng)檢測(cè)到動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù)被調(diào)用時(shí),獲取通過(guò)動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù)申請(qǐng)到的內(nèi)存地址,并獲取動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù)當(dāng)前的各上級(jí)調(diào)用函數(shù)的調(diào)用關(guān)系,在內(nèi)存占用數(shù)據(jù)庫(kù)中,記錄內(nèi)存地址與調(diào)用關(guān) 系的對(duì)應(yīng)關(guān)系。
其中,目標(biāo)應(yīng)用程序可以是被檢測(cè)是否發(fā)生內(nèi)存泄露的程序,即檢測(cè)其中的動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù)申請(qǐng)到的內(nèi)存是否在使用完畢時(shí)及時(shí)對(duì)動(dòng)態(tài)申請(qǐng)的內(nèi)存進(jìn)行釋放。
在實(shí)施中,技術(shù)人員在開(kāi)發(fā)軟件(或稱為應(yīng)用程序)編寫相應(yīng)的程序時(shí),往往會(huì)由于疏忽或錯(cuò)誤未能對(duì)已經(jīng)動(dòng)態(tài)申請(qǐng)到的內(nèi)存且不再使用的內(nèi)存進(jìn)行釋放,從而,導(dǎo)致內(nèi)存泄露的問(wèn)題。內(nèi)存資源是有限的,每次動(dòng)態(tài)申請(qǐng)內(nèi)存后,后續(xù)可申請(qǐng)的內(nèi)存資源就會(huì)減少,如果發(fā)生內(nèi)存泄露,則動(dòng)態(tài)申請(qǐng)到的內(nèi)存一直處于被占用狀態(tài),后續(xù)無(wú)法再申請(qǐng)未釋放的內(nèi)存,當(dāng)程序出現(xiàn)多處內(nèi)存泄漏時(shí),內(nèi)存資源就比較緊張,程序即會(huì)運(yùn)行緩慢,影響程序的正常工作,甚至嚴(yán)重的情況下,比如,不存在后續(xù)可申請(qǐng)的內(nèi)存,程序?qū)l(fā)生錯(cuò)誤,不能再繼續(xù)運(yùn)行,進(jìn)而,用戶無(wú)法正常該軟件,從而,檢測(cè)和定位程序中發(fā)生內(nèi)存泄露的位置變得尤為重要。
在目標(biāo)程序執(zhí)行過(guò)程中,每當(dāng)檢測(cè)到動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù)被調(diào)用時(shí),其中,動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù)可以用于動(dòng)態(tài)申請(qǐng)系統(tǒng)中的內(nèi)存,可以根據(jù)函數(shù)的參數(shù)值申請(qǐng)參數(shù)值指定大小的內(nèi)存,并且該函數(shù)可以返回申請(qǐng)到的內(nèi)存的首地址(可以稱為內(nèi)存地址),可以獲取通過(guò)動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù)申請(qǐng)到的內(nèi)存地址,并可以獲取調(diào)用該動(dòng)態(tài)申請(qǐng)函數(shù)的各函數(shù)嵌套關(guān)系,即可以獲取動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù)當(dāng)前的各上級(jí)調(diào)用函數(shù)的調(diào)用關(guān)系,并對(duì)其進(jìn)行存儲(chǔ),例如,動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù)為m函數(shù),a函數(shù)調(diào)用了m函數(shù),b函數(shù)調(diào)用了a函數(shù),在運(yùn)行b函數(shù)時(shí),即會(huì)調(diào)用a函數(shù)進(jìn)行運(yùn)行,運(yùn)行a函數(shù)時(shí),即會(huì)調(diào)用m函數(shù),通過(guò)m函數(shù)動(dòng)態(tài)申請(qǐng)內(nèi)存,此時(shí),計(jì)算設(shè)備會(huì)檢測(cè)到m函數(shù)被調(diào)用,進(jìn)而,可以獲取m函數(shù)申請(qǐng)到的內(nèi)存對(duì)應(yīng)的內(nèi)存地址,并可以獲取m函數(shù)當(dāng)前的各上級(jí)調(diào)用函數(shù)的調(diào)用關(guān)系,即為b函數(shù)調(diào)用a函數(shù),a函數(shù)調(diào)用m函數(shù),并對(duì)其進(jìn)行存儲(chǔ),或者,只可獲取并存儲(chǔ)b函數(shù)調(diào)用a函數(shù),此時(shí)即意味著是由a函數(shù)調(diào)用的m函數(shù)。獲取內(nèi)存地址以及上述調(diào)用關(guān)系后,可以記錄之間的對(duì)應(yīng)關(guān)系,并存儲(chǔ)在內(nèi)存占用數(shù)據(jù)庫(kù)中,其中,該內(nèi)存占用數(shù)據(jù)庫(kù)可以是內(nèi)存占用表,也可以是內(nèi)存占用樹(shù),即可以將內(nèi)存地址與上述調(diào)用關(guān)系的對(duì)應(yīng)關(guān)系存儲(chǔ)在表中,也可以存儲(chǔ)在樹(shù)中,比如可以是紅黑樹(shù)。
另外,在存儲(chǔ)內(nèi)存地址與上述調(diào)用關(guān)系的對(duì)應(yīng)關(guān)系時(shí),可以采用分級(jí)存儲(chǔ) 的方式,具體的,可以在內(nèi)存占用數(shù)據(jù)庫(kù)中,可以設(shè)置不同的存儲(chǔ)區(qū),每當(dāng)檢測(cè)到動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù)被調(diào)用時(shí),可以將其對(duì)應(yīng)的內(nèi)存地址與調(diào)用關(guān)系的對(duì)應(yīng)關(guān)系存儲(chǔ)在第一存儲(chǔ)區(qū)。還可以預(yù)先設(shè)置切換存儲(chǔ)區(qū)條件(可以稱為預(yù)設(shè)切換存儲(chǔ)區(qū)條件),當(dāng)存儲(chǔ)在第一存儲(chǔ)區(qū)的內(nèi)存地址與調(diào)用關(guān)系的第一對(duì)應(yīng)關(guān)系滿足預(yù)設(shè)切換存儲(chǔ)區(qū)條件時(shí),可以將第一對(duì)應(yīng)關(guān)系切換至第二存儲(chǔ)區(qū)進(jìn)行存儲(chǔ),否則,可以不進(jìn)行切換存儲(chǔ)區(qū)的相關(guān)處理,例如,預(yù)設(shè)切換存儲(chǔ)區(qū)條件可以是申請(qǐng)時(shí)間點(diǎn)距離當(dāng)前時(shí)間點(diǎn)的時(shí)長(zhǎng)大于預(yù)設(shè)時(shí)長(zhǎng),此種情況下,計(jì)算設(shè)備還可以在檢測(cè)到動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù)被調(diào)用時(shí),獲取并記錄通過(guò)動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù)申請(qǐng)到內(nèi)存地址時(shí)的申請(qǐng)時(shí)間點(diǎn),每當(dāng)達(dá)到預(yù)設(shè)的檢測(cè)周期時(shí),或者每當(dāng)檢測(cè)到存儲(chǔ)內(nèi)存地址與調(diào)用關(guān)系的對(duì)應(yīng)關(guān)系時(shí),檢測(cè)已經(jīng)存儲(chǔ)在第一存儲(chǔ)區(qū)的內(nèi)存地址與調(diào)用關(guān)系的對(duì)應(yīng)關(guān)系是否滿足預(yù)設(shè)切換存儲(chǔ)區(qū)條件。
可選的,在目標(biāo)程序的執(zhí)行過(guò)程中,還可以獲取調(diào)用動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù)的代碼行標(biāo)識(shí),相應(yīng)的,處理過(guò)程可以如下:當(dāng)檢測(cè)到動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù)被調(diào)用時(shí),獲取調(diào)用動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù)的代碼行標(biāo)識(shí)。此外,還可以進(jìn)行如下處理:在內(nèi)存占用數(shù)據(jù)庫(kù)中,記錄內(nèi)存地址與代碼行標(biāo)識(shí)、調(diào)用關(guān)系的對(duì)應(yīng)關(guān)系。
在實(shí)施中,在目標(biāo)程序的執(zhí)行過(guò)程中,當(dāng)檢測(cè)到動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù)被調(diào)用時(shí),還可以獲取調(diào)用動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù)的指令地址,進(jìn)而,可以根據(jù)指令地址與代碼位置的對(duì)應(yīng)關(guān)系,確定動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù)在調(diào)用動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù)中的代碼位置,即檢測(cè)到動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù)被調(diào)用時(shí),獲取調(diào)用動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù)的代碼行標(biāo)識(shí),其中,代碼行標(biāo)識(shí)可以是代碼在調(diào)用函數(shù)中的行號(hào)。此種情況下,可以在內(nèi)存占用數(shù)據(jù)庫(kù)中,記錄內(nèi)存地址與代碼行標(biāo)識(shí)、調(diào)用關(guān)系的對(duì)應(yīng)關(guān)系。
可選的,還可以對(duì)內(nèi)存占用數(shù)據(jù)庫(kù)中的內(nèi)存地址與調(diào)用關(guān)系的對(duì)應(yīng)關(guān)系進(jìn)行刪除,相應(yīng)的,處理過(guò)程可以如下:當(dāng)檢測(cè)到內(nèi)存地址對(duì)應(yīng)的內(nèi)存被釋放時(shí),從內(nèi)存占用數(shù)據(jù)庫(kù)中刪除內(nèi)存地址所屬的對(duì)應(yīng)關(guān)系。
在實(shí)施中,在目標(biāo)程序執(zhí)行過(guò)程中,每當(dāng)檢測(cè)到內(nèi)存釋放函數(shù)被調(diào)用時(shí),其中,內(nèi)存釋放函數(shù)可以用于對(duì)通過(guò)動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù)申請(qǐng)到的內(nèi)存進(jìn)行釋放,即檢測(cè)到內(nèi)存地址對(duì)應(yīng)的內(nèi)存被釋放時(shí),可以從內(nèi)存數(shù)據(jù)庫(kù)中刪除內(nèi)存地址所屬的對(duì)應(yīng)關(guān)系。
可選的,可以在目標(biāo)程序的執(zhí)行過(guò)程中,通過(guò)加載預(yù)設(shè)動(dòng)態(tài)鏈接庫(kù)來(lái)記錄 內(nèi)存地址與調(diào)用關(guān)系的對(duì)應(yīng)關(guān)系,以便后續(xù)確定發(fā)生內(nèi)存泄露的位置的相關(guān)處理,相應(yīng)的,步驟201的處理過(guò)程可以如下:在目標(biāo)程序執(zhí)行過(guò)程中,當(dāng)檢測(cè)到動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù)的調(diào)用指令時(shí),執(zhí)行預(yù)設(shè)動(dòng)態(tài)鏈接庫(kù)中的程序,以執(zhí)行動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù),獲取通過(guò)動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù)申請(qǐng)到的內(nèi)存地址,并獲取調(diào)用指令的各上級(jí)調(diào)用函數(shù)的調(diào)用關(guān)系,在內(nèi)存占用數(shù)據(jù)庫(kù)中,記錄內(nèi)存地址與調(diào)用關(guān)系的對(duì)應(yīng)關(guān)系。還可以進(jìn)行如下處理:當(dāng)檢測(cè)到對(duì)內(nèi)存地址對(duì)應(yīng)的內(nèi)存的釋放指令時(shí),執(zhí)行預(yù)設(shè)動(dòng)態(tài)鏈接庫(kù)中的程序,釋放內(nèi)存,并從內(nèi)存占用數(shù)據(jù)庫(kù)中刪除內(nèi)存地址所屬的對(duì)應(yīng)關(guān)系。
在實(shí)施中,可以預(yù)先設(shè)置動(dòng)態(tài)鏈接庫(kù)(可以稱為預(yù)設(shè)動(dòng)態(tài)鏈接庫(kù)),在目標(biāo)程序執(zhí)行過(guò)程中,當(dāng)檢測(cè)到動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù)的調(diào)用指令時(shí),可以執(zhí)行預(yù)設(shè)動(dòng)態(tài)鏈接庫(kù)中的程序,以便執(zhí)行動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù),此時(shí),預(yù)設(shè)動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù)中的程序相當(dāng)于是動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù)的具體代碼,當(dāng)預(yù)設(shè)動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù)中的程序全部執(zhí)行完畢時(shí),即相當(dāng)于動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù)執(zhí)行完畢。具體的,執(zhí)行預(yù)設(shè)動(dòng)態(tài)鏈接庫(kù)中的程序,可以按照上述步驟201所述的方式獲取通過(guò)動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù)申請(qǐng)到的內(nèi)存地址,并獲取調(diào)用指令的各上級(jí)調(diào)用函數(shù)的調(diào)用關(guān)系,即獲取目標(biāo)程序中調(diào)用動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù)的各上級(jí)調(diào)用函數(shù)的調(diào)用關(guān)系,并可以在內(nèi)存占用數(shù)據(jù)庫(kù)中,記錄內(nèi)存地址與調(diào)用關(guān)系的對(duì)應(yīng)關(guān)系。這樣,無(wú)需修改目標(biāo)程序,通過(guò)執(zhí)行預(yù)設(shè)動(dòng)態(tài)鏈接庫(kù)中的程序即可獲取目標(biāo)程序通過(guò)動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù)申請(qǐng)到的內(nèi)存地址,以及對(duì)應(yīng)的各上級(jí)調(diào)用函數(shù)的調(diào)用關(guān)系,另外,利用此種方式,若目標(biāo)程序無(wú)法修改時(shí),其中,當(dāng)目標(biāo)程序是標(biāo)準(zhǔn)c函數(shù)或者第三方程序時(shí),技術(shù)人員無(wú)法對(duì)源代碼進(jìn)行修改,也可以通過(guò)執(zhí)行預(yù)設(shè)動(dòng)態(tài)鏈接庫(kù)中的程序獲取相關(guān)的信息,以便進(jìn)行后續(xù)確定發(fā)生內(nèi)存泄露的位置的相關(guān)處理。
針對(duì)刪除內(nèi)存地址所屬的對(duì)應(yīng)關(guān)系的情況,在目標(biāo)程序的執(zhí)行過(guò)程中,當(dāng)檢測(cè)到對(duì)內(nèi)存地址對(duì)應(yīng)的內(nèi)存的釋放指令時(shí),也可以執(zhí)行預(yù)設(shè)動(dòng)態(tài)鏈接庫(kù)中的程序,對(duì)內(nèi)存地址對(duì)應(yīng)的內(nèi)存進(jìn)行釋放,并可以從內(nèi)存占用數(shù)據(jù)庫(kù)中刪除內(nèi)存地址所屬的對(duì)應(yīng)關(guān)系。
步驟202,根據(jù)記錄的調(diào)用關(guān)系,確定發(fā)生內(nèi)存泄露的位置。
在實(shí)施中,獲取到內(nèi)存地址對(duì)應(yīng)的調(diào)用關(guān)系后,可以根據(jù)記錄的調(diào)用關(guān)系,確定發(fā)生內(nèi)存泄露的位置,具體的,計(jì)算設(shè)備還可以在獲取到通過(guò)動(dòng)態(tài)內(nèi)存申 請(qǐng)函數(shù)申請(qǐng)到的內(nèi)存地址后,獲取該內(nèi)存地址對(duì)應(yīng)的申請(qǐng)時(shí)間點(diǎn),此種情況下,可以確定申請(qǐng)時(shí)間點(diǎn)距離當(dāng)前時(shí)間點(diǎn)的時(shí)長(zhǎng)大于預(yù)設(shè)時(shí)長(zhǎng)的內(nèi)存地址,并確定該內(nèi)存地址對(duì)應(yīng)的調(diào)用關(guān)系,進(jìn)而,可以根據(jù)確定出的申請(qǐng)時(shí)間點(diǎn)距離當(dāng)前時(shí)間點(diǎn)的時(shí)長(zhǎng)大于預(yù)設(shè)時(shí)長(zhǎng)的內(nèi)存地址對(duì)應(yīng)的調(diào)用關(guān)系,確定發(fā)生內(nèi)存泄露的位置。
可選的,可以通過(guò)確定出的滿足預(yù)設(shè)選取條件的調(diào)用關(guān)系,確定發(fā)生內(nèi)存泄露的位置,相應(yīng)的,步驟202的處理過(guò)程可以如下:確定每個(gè)調(diào)用關(guān)系對(duì)應(yīng)的內(nèi)存申請(qǐng)次數(shù)和內(nèi)存釋放次數(shù),確定每個(gè)調(diào)用關(guān)系對(duì)應(yīng)的內(nèi)存申請(qǐng)次數(shù)和內(nèi)存釋放次數(shù)的差值,在每個(gè)調(diào)用關(guān)系對(duì)應(yīng)的內(nèi)存申請(qǐng)次數(shù)和內(nèi)存釋放次數(shù)的差值中,確定滿足預(yù)設(shè)選取條件的差值,選取滿足預(yù)設(shè)選取條件的差值對(duì)應(yīng)的目標(biāo)調(diào)用關(guān)系;將目標(biāo)調(diào)用關(guān)系對(duì)應(yīng)的程序位置確定為發(fā)生內(nèi)存泄露的位置。
在實(shí)施中,在目標(biāo)程序執(zhí)行過(guò)程中,每獲取到動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù)當(dāng)前的各上級(jí)調(diào)用函數(shù)的調(diào)用關(guān)系時(shí),可以存儲(chǔ)調(diào)用關(guān)系對(duì)應(yīng)的內(nèi)存申請(qǐng)次數(shù)和內(nèi)存釋放次數(shù),即目標(biāo)程序可能在多處代碼位置對(duì)動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù)進(jìn)行多次調(diào)用,并且多處調(diào)用動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù)的各上級(jí)調(diào)用函數(shù)的調(diào)用關(guān)系可能相同,此時(shí),可以對(duì)相同調(diào)用關(guān)系的相關(guān)信息進(jìn)行統(tǒng)一存儲(chǔ),也就是說(shuō),對(duì)于多次出現(xiàn)的調(diào)用關(guān)系,只存儲(chǔ)一次該調(diào)用關(guān)系,目標(biāo)程序中每出現(xiàn)一次該調(diào)用關(guān)系,可以對(duì)該調(diào)用關(guān)系對(duì)應(yīng)的內(nèi)存申請(qǐng)次數(shù)進(jìn)行更新。具體的,每獲取到動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù)當(dāng)前的各上級(jí)調(diào)用函數(shù)的調(diào)用關(guān)系時(shí),可以判斷是否已經(jīng)存儲(chǔ)有該調(diào)用關(guān)系,若已經(jīng)存儲(chǔ)有該調(diào)用關(guān)系,可以對(duì)該調(diào)用關(guān)系對(duì)應(yīng)的內(nèi)存申請(qǐng)次數(shù)進(jìn)行更新,即可以將內(nèi)存申請(qǐng)次數(shù)加1,若沒(méi)有存儲(chǔ)有該調(diào)用關(guān)系,即該目標(biāo)程序此時(shí)是第一次出現(xiàn),可以存儲(chǔ)該調(diào)用關(guān)系,同時(shí),該調(diào)用關(guān)系對(duì)應(yīng)的內(nèi)存申請(qǐng)次數(shù)可以記為預(yù)設(shè)的初始值,比如可以是1。另外,針對(duì)存儲(chǔ)調(diào)用關(guān)系對(duì)應(yīng)的內(nèi)存申請(qǐng)次數(shù)和內(nèi)存釋放次數(shù)的情況,內(nèi)存占用數(shù)據(jù)庫(kù)中記錄內(nèi)存地址與調(diào)用關(guān)系的對(duì)應(yīng)關(guān)系,可以記錄內(nèi)存地址與調(diào)用關(guān)系的標(biāo)識(shí)的對(duì)應(yīng)關(guān)系,其中,調(diào)用關(guān)系的標(biāo)識(shí)具有唯一性,可以是調(diào)用關(guān)系對(duì)應(yīng)的內(nèi)存地址,也可以是按照預(yù)設(shè)規(guī)則,對(duì)每個(gè)調(diào)用關(guān)系標(biāo)記的標(biāo)識(shí),比如是阿拉伯?dāng)?shù)字。
對(duì)于檢測(cè)到內(nèi)存地址對(duì)應(yīng)的內(nèi)存被釋放的情況,可以獲取被釋放內(nèi)存對(duì)應(yīng)的內(nèi)存地址,進(jìn)而,可以在內(nèi)存占用數(shù)據(jù)庫(kù)中記錄的內(nèi)存地址與調(diào)用關(guān)系的對(duì)應(yīng)關(guān)系中,確定被釋放內(nèi)存對(duì)應(yīng)的內(nèi)存地址對(duì)應(yīng)的調(diào)用關(guān)系,并可以根據(jù)確定 的調(diào)用關(guān)系獲取該調(diào)用關(guān)系對(duì)應(yīng)的內(nèi)存釋放次數(shù),并對(duì)其進(jìn)行更新,即可以將內(nèi)存釋放次數(shù)加1。此外,對(duì)于采用分級(jí)存儲(chǔ)的方式存儲(chǔ)內(nèi)存地址與調(diào)用關(guān)系的對(duì)應(yīng)關(guān)系的情況,當(dāng)檢測(cè)到內(nèi)存地址對(duì)應(yīng)的內(nèi)存被釋放時(shí),可以首先在第一存儲(chǔ)區(qū)存儲(chǔ)的內(nèi)存地址與調(diào)用關(guān)系的對(duì)應(yīng)關(guān)系中,查找被釋放的內(nèi)存對(duì)應(yīng)的內(nèi)存地址對(duì)應(yīng)的調(diào)用關(guān)系,若第一存儲(chǔ)區(qū)中不包含被釋放的內(nèi)存對(duì)應(yīng)的內(nèi)存地址時(shí),可以再在第二存儲(chǔ)區(qū)存儲(chǔ)的內(nèi)存地址與調(diào)用關(guān)系的對(duì)應(yīng)關(guān)系中,查找被釋放的內(nèi)存對(duì)應(yīng)的內(nèi)存地址對(duì)應(yīng)的調(diào)用關(guān)系。這樣,可以有效提高確定被釋放的內(nèi)存對(duì)應(yīng)的內(nèi)存地址對(duì)應(yīng)的調(diào)用關(guān)系的效率。
可以預(yù)先設(shè)置差值獲取觸發(fā)事件,其中,差值獲取觸發(fā)事件可以是達(dá)到預(yù)設(shè)的差值獲取周期,也可以是檢測(cè)到存儲(chǔ)內(nèi)存地址與調(diào)用關(guān)系的對(duì)應(yīng)關(guān)系,每當(dāng)檢測(cè)到預(yù)設(shè)的差值獲取觸發(fā)事件發(fā)生時(shí),可以確定已經(jīng)存儲(chǔ)的每個(gè)調(diào)用關(guān)系對(duì)應(yīng)的內(nèi)存申請(qǐng)次數(shù)和內(nèi)存釋放次數(shù),確定每個(gè)調(diào)用關(guān)系對(duì)應(yīng)的內(nèi)存申請(qǐng)次數(shù)和內(nèi)存釋放次數(shù)的差值。之后,可以在每個(gè)調(diào)用關(guān)系對(duì)應(yīng)的內(nèi)存申請(qǐng)次數(shù)和內(nèi)存釋放次數(shù)的差值中,確定滿足預(yù)設(shè)選取條件的差值,并且可以選取滿足預(yù)設(shè)選取條件的差值對(duì)應(yīng)的目標(biāo)調(diào)用關(guān)系,進(jìn)而,可以將目標(biāo)調(diào)用關(guān)系對(duì)應(yīng)的程序位置確定為發(fā)生內(nèi)存泄露的位置,即可以將目標(biāo)程序中出現(xiàn)目標(biāo)調(diào)用關(guān)系的代碼位置確定為發(fā)生內(nèi)存泄露的位置。
可選的,可以根據(jù)較大的內(nèi)存申請(qǐng)次數(shù)和內(nèi)存釋放次數(shù)的差值對(duì)應(yīng)的調(diào)用關(guān)系,確定發(fā)生內(nèi)存泄露的位置,相應(yīng)的,處理過(guò)程可以如下:在每個(gè)調(diào)用關(guān)系對(duì)應(yīng)的內(nèi)存申請(qǐng)次數(shù)和內(nèi)存釋放次數(shù)的差值中,獲取預(yù)設(shè)數(shù)目個(gè)最大的差值,并確定預(yù)設(shè)數(shù)目個(gè)最大的差值對(duì)應(yīng)的目標(biāo)調(diào)用關(guān)系。
在實(shí)施中,確定出每個(gè)調(diào)用關(guān)系對(duì)應(yīng)的內(nèi)存申請(qǐng)次數(shù)和內(nèi)存釋放次數(shù)的差值后,可以按照差值由大到小的順序,對(duì)其進(jìn)行排序,可以從中獲取排在前列的預(yù)設(shè)數(shù)目個(gè)差值對(duì)應(yīng)的目標(biāo)調(diào)用關(guān)系。
此外,獲取預(yù)設(shè)數(shù)目個(gè)最大的差值對(duì)應(yīng)的目標(biāo)調(diào)用關(guān)系后,還可以對(duì)選取的預(yù)設(shè)數(shù)目個(gè)最大的差值對(duì)應(yīng)的目標(biāo)調(diào)用關(guān)系進(jìn)行更新,具體的,當(dāng)檢測(cè)到除目標(biāo)調(diào)用關(guān)系之外的其他調(diào)用關(guān)系對(duì)應(yīng)的內(nèi)存申請(qǐng)次數(shù)和內(nèi)存釋放次數(shù)的差值增加時(shí),可以將其他調(diào)用關(guān)系對(duì)應(yīng)的內(nèi)存申請(qǐng)次數(shù)和內(nèi)存釋放次數(shù)的差值與每個(gè)目標(biāo)調(diào)用關(guān)系對(duì)應(yīng)的內(nèi)存申請(qǐng)次數(shù)和內(nèi)存釋放次數(shù)的差值進(jìn)行比較,若前者大于后者,可以對(duì)目標(biāo)調(diào)用關(guān)系進(jìn)行更新,即可以將更大的內(nèi)存申請(qǐng)次數(shù)和內(nèi) 存釋放次數(shù)的差值對(duì)應(yīng)的其他調(diào)用關(guān)系替換目標(biāo)調(diào)用關(guān)系中較小的內(nèi)存申請(qǐng)次數(shù)和內(nèi)存釋放次數(shù)的差值對(duì)應(yīng)的調(diào)用關(guān)系,也就是說(shuō),在目標(biāo)程序執(zhí)行的過(guò)程中,選取的目標(biāo)調(diào)用關(guān)系對(duì)應(yīng)的內(nèi)存申請(qǐng)次數(shù)和內(nèi)存釋放次數(shù)的差值在所有的調(diào)用關(guān)系對(duì)應(yīng)的內(nèi)存申請(qǐng)次數(shù)和內(nèi)存釋放次數(shù)的差值中是最大的。另外,還可以記錄每個(gè)調(diào)用關(guān)系對(duì)應(yīng)的歷史最大未釋放次數(shù),其中,歷史最大未釋放次數(shù)可以是到目前為止,調(diào)用關(guān)系對(duì)應(yīng)的內(nèi)存申請(qǐng)次數(shù)與內(nèi)存釋放次數(shù)的最大差值,當(dāng)檢測(cè)到除目標(biāo)調(diào)用關(guān)系之外的其他調(diào)用關(guān)系對(duì)應(yīng)的內(nèi)存申請(qǐng)次數(shù)和內(nèi)存釋放次數(shù)的差值大于對(duì)應(yīng)的歷史最大未釋放次數(shù)時(shí),可以將其他調(diào)用關(guān)系對(duì)應(yīng)的內(nèi)存申請(qǐng)次數(shù)和內(nèi)存釋放次數(shù)的差值與每個(gè)目標(biāo)調(diào)用關(guān)系對(duì)應(yīng)的內(nèi)存申請(qǐng)次數(shù)和內(nèi)存釋放次數(shù)的差值進(jìn)行比較,若前者大于后者,可以對(duì)目標(biāo)調(diào)用關(guān)系進(jìn)行更新,即可以將更大的內(nèi)存申請(qǐng)次數(shù)和內(nèi)存釋放次數(shù)的差值對(duì)應(yīng)的其他調(diào)用關(guān)系替換目標(biāo)調(diào)用關(guān)系中較小的內(nèi)存申請(qǐng)次數(shù)和內(nèi)存釋放次數(shù)的差值對(duì)應(yīng)的調(diào)用關(guān)系。
本發(fā)明實(shí)施例還提供了一種獲取調(diào)用關(guān)系的方法,其中,可以通過(guò)目標(biāo)程序的棧中當(dāng)前記錄的信息,獲取動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù)當(dāng)前的各上級(jí)調(diào)用函數(shù)的調(diào)用關(guān)系。
如圖3所示,該方法的具體處理流程可以包括如下的步驟:
步驟301,獲取目標(biāo)程序的棧中當(dāng)前記錄的返回地址,并確定每個(gè)返回地址在棧中的排列順序。
其中,返回地址可以是運(yùn)行完被調(diào)用函數(shù)后接下來(lái)運(yùn)行的代碼對(duì)應(yīng)的指令地址,例如,在b函數(shù)的第50行調(diào)用a函數(shù),運(yùn)行到b函數(shù)的第50行時(shí),即開(kāi)始運(yùn)行a函數(shù),如果運(yùn)行完a函數(shù)后即a函數(shù)返回后,將執(zhí)行b函數(shù)的第51行,則b函數(shù)的第51行代碼對(duì)應(yīng)的指令地址即可稱為返回地址,可以稱作是a函數(shù)的返回地址。
在實(shí)施中,計(jì)算設(shè)備運(yùn)行目標(biāo)程序時(shí),會(huì)將程序加載到內(nèi)存中,其中,存儲(chǔ)程序的那一段內(nèi)存可以稱為是代碼段,程序中的每一條代碼(指令)都會(huì)對(duì)應(yīng)一個(gè)內(nèi)存地址,并且在運(yùn)行目標(biāo)程序中的函數(shù)時(shí),會(huì)將函數(shù)的相關(guān)信息壓進(jìn)目標(biāo)程序的棧中,其中,函數(shù)的相關(guān)信息可以是函數(shù)對(duì)應(yīng)的返回地址(運(yùn)行某函數(shù)時(shí),函數(shù)的返回地址最先進(jìn)棧)、函數(shù)涉及的局部變量、函數(shù)的參數(shù)值,也 就是說(shuō),該函數(shù)的相關(guān)信息會(huì)占用棧的某一段空間。函數(shù)被壓進(jìn)棧后,可以通過(guò)當(dāng)前的棧幀地址獲取該函數(shù)所在棧中的首地址,其中,棧幀地址可以是該函數(shù)對(duì)應(yīng)的相關(guān)信息占用的棧的某一段空間的首地址,即通過(guò)棧幀地址可以獲取函數(shù)的返回地址在棧中的位置。當(dāng)該函數(shù)運(yùn)行結(jié)束后,該函數(shù)對(duì)應(yīng)的相關(guān)信息即會(huì)出棧。
綜上所述,如果存在多級(jí)函數(shù)調(diào)用時(shí),對(duì)于沒(méi)有運(yùn)行結(jié)束的函數(shù),棧中會(huì)存儲(chǔ)有每個(gè)函數(shù)的相關(guān)信息,即會(huì)存儲(chǔ)每個(gè)函數(shù)對(duì)應(yīng)的返回地址,并且是在運(yùn)行函數(shù)時(shí),函數(shù)的相關(guān)信息才會(huì)被壓進(jìn)棧,所以可以根據(jù)棧中記錄的信息獲取當(dāng)前的函數(shù)調(diào)用關(guān)系,如果有新的函數(shù)的相關(guān)信息被壓進(jìn)棧,則上一函數(shù)(調(diào)用該當(dāng)前進(jìn)棧的函數(shù)的函數(shù))對(duì)應(yīng)的棧幀地址也會(huì)被壓進(jìn)棧進(jìn)行存儲(chǔ),其中,上一函數(shù)對(duì)應(yīng)的棧幀地址與當(dāng)前運(yùn)行的函數(shù)的返回地址在棧中相鄰分布,當(dāng)前的棧幀地址即是當(dāng)前運(yùn)行的函數(shù)對(duì)應(yīng)的棧幀地址,由此,我們可以根據(jù)當(dāng)前的棧幀地址獲取當(dāng)前函數(shù)對(duì)應(yīng)的返回地址,然后可以根據(jù)與該返回地址相鄰分布的棧幀地址獲取上一函數(shù)的返回地址,以此類推,可以目標(biāo)程序的棧中當(dāng)前記錄的返回地址,并可以確定每個(gè)返回地址在棧中的排列順序,例如,目標(biāo)程序的主函數(shù)調(diào)用了b函數(shù),b函數(shù)調(diào)用了a函數(shù),a函數(shù)調(diào)用了m函數(shù),則運(yùn)行b函數(shù)時(shí),b函數(shù)的相關(guān)信息進(jìn)棧,首先進(jìn)棧的是b函數(shù)的返回地址(若主函數(shù)在第50行調(diào)用了b函數(shù),b函數(shù)的返回地址可以是主函數(shù)的第51行在代碼段中的地址),如圖4所示,當(dāng)前的棧幀地址是b函數(shù)在棧中的首地址,比如0x123470,運(yùn)行到a函數(shù)時(shí),b函數(shù)的相關(guān)信息進(jìn)棧,當(dāng)前的棧幀地址是a函數(shù)在棧中的首地址,即是a函數(shù)的返回地址在棧中的地址,比如是0x123448,此時(shí)b函數(shù)在棧中的首地址0x123470會(huì)被壓進(jìn)棧,并且a函數(shù)的返回地址與b函數(shù)的棧幀地址相鄰分布,對(duì)于32位系統(tǒng)來(lái)講,0x123470在棧的地址可以是0x123452,運(yùn)行到m函數(shù)時(shí),m函數(shù)的相關(guān)信息進(jìn)棧,當(dāng)前的棧幀地址是m函數(shù)在棧中的首地址,即是m函數(shù)的返回地址在棧中的地址,比如是0x123412,此時(shí)a函數(shù)在棧中的首地址0x123448會(huì)被壓進(jìn)棧,并且m函數(shù)的返回地址與a函數(shù)的棧幀地址相鄰分布,可以是0x123416,這樣,可以根據(jù)當(dāng)前棧幀地址0x123412獲取m函數(shù)的返回地址,即地址0x123412中存儲(chǔ)的信息,可以根據(jù)與其相鄰分布的地址0x123416獲取函數(shù)a的返回地址所在棧中的地址,即0x123448,進(jìn)而可以根據(jù)與地址0x123448相鄰分布的地址0x123452存儲(chǔ)的b函數(shù)的返回地址在棧中 的地址0x123470獲取b函數(shù)的返回地址,從而,可以獲取目標(biāo)程序的棧中當(dāng)前記錄的返回地址,并確定每個(gè)返回地址在棧中的排列順序,并可以對(duì)其進(jìn)行存儲(chǔ)。
步驟302,根據(jù)目標(biāo)程序的指令地址與函數(shù)標(biāo)識(shí)的對(duì)應(yīng)關(guān)系,分別確定與每個(gè)返回地址相同的指令地址所對(duì)應(yīng)的函數(shù)標(biāo)識(shí),得到每個(gè)返回地址對(duì)應(yīng)的函數(shù)標(biāo)識(shí)。
其中,指令地址可以是目標(biāo)程序中的每條指令對(duì)應(yīng)的地址,即在代碼段中的位置。
在實(shí)施中,獲取目標(biāo)程序的棧中當(dāng)前記錄的返回地址后,可以獲取本地存儲(chǔ)的目標(biāo)程序的指令地址與函數(shù)標(biāo)識(shí)的對(duì)應(yīng)關(guān)系,即指令地址對(duì)應(yīng)的代碼所屬的函數(shù)的對(duì)應(yīng)關(guān)系,并可以在目標(biāo)程序的指令地址與函數(shù)標(biāo)識(shí)的對(duì)應(yīng)關(guān)系中,獲取與返回地址相同的指令地址所對(duì)應(yīng)的函數(shù)標(biāo)識(shí),其中,被調(diào)用函數(shù)的返回地址即是調(diào)用函數(shù)的指令地址,得到每個(gè)返回地址對(duì)應(yīng)的函數(shù)標(biāo)識(shí),例如,b函數(shù)調(diào)用a函數(shù),a函數(shù)調(diào)用m函數(shù),可以根據(jù)獲取的m函數(shù)的返回地址(即與a函數(shù)中調(diào)用m函數(shù)代碼的下一條代碼對(duì)應(yīng)的指令地址)以及a函數(shù)中的代碼對(duì)應(yīng)的指令地址與a函數(shù)的對(duì)應(yīng)關(guān)系,得到m函數(shù)的返回地址對(duì)應(yīng)的函數(shù)標(biāo)識(shí),以此類推,也可得到a函數(shù)的返回地址對(duì)應(yīng)的函數(shù)為b函數(shù)。
可選的,得到每個(gè)返回地址對(duì)應(yīng)的函數(shù)標(biāo)識(shí)之后,還可以對(duì)得到的函數(shù)標(biāo)識(shí)進(jìn)行過(guò)濾,相應(yīng)的,處理過(guò)程可以如下:在每個(gè)返回地址對(duì)應(yīng)的函數(shù)標(biāo)識(shí)中,確定滿足預(yù)設(shè)過(guò)濾條件的函數(shù)標(biāo)識(shí),選取滿足預(yù)設(shè)過(guò)濾條件的函數(shù)標(biāo)識(shí)對(duì)應(yīng)的返回地址。
在實(shí)施中,可以預(yù)先設(shè)置過(guò)濾條件(可以稱為預(yù)設(shè)過(guò)濾條件)并存儲(chǔ),其中,可以通過(guò)預(yù)設(shè)過(guò)濾條件將c標(biāo)準(zhǔn)函數(shù)或者已經(jīng)確定不會(huì)發(fā)生內(nèi)存泄露的函數(shù)過(guò)濾掉。得到目標(biāo)程序的棧中當(dāng)前記錄的返回地址對(duì)應(yīng)的函數(shù)標(biāo)識(shí)后,可以判斷對(duì)應(yīng)的函數(shù)標(biāo)識(shí)是否滿足預(yù)設(shè)過(guò)濾條件,可以在獲取的所有的函數(shù)標(biāo)識(shí)中選取滿足預(yù)設(shè)過(guò)濾條件的函數(shù)標(biāo)識(shí),進(jìn)而可以根據(jù)得到的每個(gè)返回地址與函數(shù)標(biāo)識(shí)的對(duì)應(yīng)關(guān)系,選取滿足預(yù)設(shè)過(guò)濾條件的函數(shù)標(biāo)識(shí)對(duì)應(yīng)的返回地址。
步驟303,根據(jù)每個(gè)返回地址在棧中的排列順序,以及每個(gè)返回地址對(duì)應(yīng)的函數(shù)標(biāo)識(shí),確定動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù)當(dāng)前的各上級(jí)調(diào)用函數(shù)的調(diào)用關(guān)系。
在實(shí)施中,得到每個(gè)返回地址對(duì)應(yīng)的函數(shù)標(biāo)識(shí)后,可以根據(jù)獲取的每個(gè)返 回地址在棧中的排列順序,以及每個(gè)返回地址對(duì)應(yīng)的函數(shù)標(biāo)識(shí),確定動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù)當(dāng)前的各上級(jí)調(diào)用函數(shù)的調(diào)用關(guān)系。由于調(diào)用函數(shù)先入棧,被調(diào)用的函數(shù)后入棧,從而,可以根據(jù)獲取的每個(gè)返回地址在棧中的排列順序獲知函數(shù)的調(diào)用關(guān)系。
可選的,對(duì)于對(duì)每個(gè)返回地址對(duì)應(yīng)的函數(shù)標(biāo)識(shí)進(jìn)行過(guò)濾的情況,相應(yīng)的,步驟303的處理過(guò)程可以如下:根據(jù)選取的返回地址在棧中的排列順序,以及滿足預(yù)設(shè)過(guò)濾條件的函數(shù)標(biāo)識(shí),確定動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù)當(dāng)前的各上級(jí)調(diào)用函數(shù)的調(diào)用關(guān)系。
在實(shí)施中,過(guò)濾掉一般部分函數(shù)標(biāo)識(shí)后,可以根據(jù)剩余的返回地址在棧中的排列順序,以及剩余的返回地址對(duì)應(yīng)的函數(shù)標(biāo)識(shí),確定動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù)當(dāng)前的各上級(jí)調(diào)用函數(shù)的調(diào)用關(guān)系。另外,為提高處理速度,可以預(yù)先設(shè)置獲取的返回地址的數(shù)目,進(jìn)而,可以根據(jù)預(yù)設(shè)數(shù)目個(gè)返回地址,以及返回地址在棧中的排列順序,確定調(diào)用關(guān)系動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù)當(dāng)前的各上級(jí)調(diào)用函數(shù)的調(diào)用關(guān)系,對(duì)于此種情況,設(shè)置過(guò)濾條件,可以獲取較多對(duì)確定發(fā)生內(nèi)存泄露的位置更有意義的信息。
本發(fā)明實(shí)施例中,在目標(biāo)程序執(zhí)行過(guò)程中,當(dāng)檢測(cè)到動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù)被調(diào)用時(shí),獲取通過(guò)動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù)申請(qǐng)到的內(nèi)存地址,并獲取動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù)當(dāng)前的各上級(jí)調(diào)用函數(shù)的調(diào)用關(guān)系,在內(nèi)存占用數(shù)據(jù)庫(kù)中,記錄內(nèi)存地址與調(diào)用關(guān)系的對(duì)應(yīng)關(guān)系,根據(jù)記錄的調(diào)用關(guān)系,確定發(fā)生內(nèi)存泄露的位置。這樣,在目標(biāo)程序執(zhí)行過(guò)程中,可以通過(guò)記錄的調(diào)用關(guān)系,縮小查找的范圍,在目標(biāo)程序中快速找到發(fā)生內(nèi)存泄露的代碼位置,從而,可以提高查找內(nèi)存泄露的代碼位置的效率。
基于相同的技術(shù)構(gòu)思,本發(fā)明實(shí)施例還提供了一種確定內(nèi)存泄露位置的裝置,如圖1所示,該裝置可以實(shí)現(xiàn)上述步驟201-202,步驟301-303所述的方法,該述裝置包括處理器110、存儲(chǔ)器120,其中:
所述處理器110,用于在目標(biāo)程序執(zhí)行過(guò)程中,當(dāng)檢測(cè)到動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù)被調(diào)用時(shí),獲取通過(guò)所述動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù)申請(qǐng)到的內(nèi)存地址,并獲取所述動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù)當(dāng)前的各上級(jí)調(diào)用函數(shù)的調(diào)用關(guān)系,在所述存儲(chǔ)器120中建立的內(nèi)存占用數(shù)據(jù)庫(kù)中,記錄所述內(nèi)存地址與所述調(diào)用關(guān)系的對(duì)應(yīng)關(guān)系;根據(jù)記 錄的調(diào)用關(guān)系,確定發(fā)生內(nèi)存泄露的位置。
在實(shí)施中,在目標(biāo)程序執(zhí)行過(guò)程中,處理器110每當(dāng)檢測(cè)到動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù)被調(diào)用時(shí),其中,動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù)可以用于動(dòng)態(tài)申請(qǐng)系統(tǒng)中的內(nèi)存,可以根據(jù)函數(shù)的參數(shù)值申請(qǐng)指定大小的內(nèi)存,并且該函數(shù)可以返回申請(qǐng)到的內(nèi)存的首地址(可以稱為內(nèi)存地址),可以獲取通過(guò)動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù)申請(qǐng)到的內(nèi)存地址,并可以獲取調(diào)用該動(dòng)態(tài)申請(qǐng)函數(shù)的各函數(shù)嵌套關(guān)系,即可以獲取動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù)當(dāng)前的各上級(jí)調(diào)用函數(shù)的調(diào)用關(guān)系,并對(duì)其進(jìn)行存儲(chǔ),獲取內(nèi)存地址以及上述調(diào)用關(guān)系后,可以記錄之間的對(duì)應(yīng)關(guān)系,并存儲(chǔ)在存儲(chǔ)器120中建立的內(nèi)存占用數(shù)據(jù)庫(kù)中,其中,該內(nèi)存占用數(shù)據(jù)庫(kù)可以是內(nèi)存占用表,也可以是內(nèi)存占用樹(shù),即可以將內(nèi)存地址與上述調(diào)用關(guān)系的對(duì)應(yīng)關(guān)系存儲(chǔ)在表中,也可以存儲(chǔ)在樹(shù)中,比如可以是紅黑樹(shù)。在目標(biāo)程序執(zhí)行過(guò)程中,每獲取到動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù)當(dāng)前的各上級(jí)調(diào)用函數(shù)的調(diào)用關(guān)系時(shí),可以存儲(chǔ)調(diào)用關(guān)系對(duì)應(yīng)的內(nèi)存申請(qǐng)次數(shù)和內(nèi)存釋放次數(shù)。獲取到內(nèi)存地址對(duì)應(yīng)的調(diào)用關(guān)系后,可以根據(jù)記錄的調(diào)用關(guān)系,確定發(fā)生內(nèi)存泄露的位置,具體的,計(jì)算設(shè)備還可以在獲取到通過(guò)動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù)申請(qǐng)到的內(nèi)存地址后,獲取該內(nèi)存地址對(duì)應(yīng)的申請(qǐng)時(shí)間點(diǎn),此種情況下,可以確定申請(qǐng)時(shí)間點(diǎn)距離當(dāng)前時(shí)間點(diǎn)的時(shí)長(zhǎng)大于預(yù)設(shè)時(shí)長(zhǎng)的內(nèi)存地址,并確定該內(nèi)存地址對(duì)應(yīng)的調(diào)用關(guān)系,進(jìn)而,可以根據(jù)確定出的申請(qǐng)時(shí)間點(diǎn)距離當(dāng)前時(shí)間點(diǎn)的時(shí)長(zhǎng)大于預(yù)設(shè)時(shí)長(zhǎng)的內(nèi)存地址對(duì)應(yīng)的調(diào)用關(guān)系,確定發(fā)生內(nèi)存泄露的位置。
可選的,所述處理器110,還用于:
當(dāng)檢測(cè)到動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù)被調(diào)用時(shí),獲取調(diào)用所述動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù)的代碼行標(biāo)識(shí);
所述處理器110,具體用于:
在內(nèi)存占用數(shù)據(jù)庫(kù)中,記錄所述內(nèi)存地址與所述代碼行標(biāo)識(shí)、所述調(diào)用關(guān)系的對(duì)應(yīng)關(guān)系。
在實(shí)施中,在目標(biāo)程序的執(zhí)行過(guò)程中,當(dāng)處理器110檢測(cè)到動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù)被調(diào)用時(shí),還可以獲取調(diào)用動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù)的指令地址,進(jìn)而,可以根據(jù)指令地址與代碼位置的對(duì)應(yīng)關(guān)系,確定動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù)在調(diào)用動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù)中的代碼位置,即檢測(cè)到動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù)被調(diào)用時(shí),獲取調(diào)用動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù)的代碼行標(biāo)識(shí),其中,代碼行標(biāo)識(shí)可以是代碼在調(diào)用函數(shù)中的行號(hào)。 此種情況下,可以在內(nèi)存占用數(shù)據(jù)庫(kù)中,記錄內(nèi)存地址與代碼行標(biāo)識(shí)、調(diào)用關(guān)系的對(duì)應(yīng)關(guān)系。
可選的,所述處理器110,具體用于:
獲取所述目標(biāo)程序的棧中當(dāng)前記錄的返回地址,并確定每個(gè)返回地址在所述棧中的排列順序;
根據(jù)所述目標(biāo)程序的指令地址與函數(shù)標(biāo)識(shí)的對(duì)應(yīng)關(guān)系,分別確定與每個(gè)返回地址相同的指令地址所對(duì)應(yīng)的函數(shù)標(biāo)識(shí),得到每個(gè)返回地址對(duì)應(yīng)的函數(shù)標(biāo)識(shí);
根據(jù)所述每個(gè)返回地址在所述棧中的排列順序,以及每個(gè)返回地址對(duì)應(yīng)的函數(shù)標(biāo)識(shí),確定所述動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù)當(dāng)前的各上級(jí)調(diào)用函數(shù)的調(diào)用關(guān)系。
在實(shí)施中,在運(yùn)行目標(biāo)程序中的函數(shù)時(shí),處理器110會(huì)將函數(shù)的相關(guān)信息壓進(jìn)目標(biāo)程序的棧中,其中,函數(shù)的相關(guān)信息可以是函數(shù)對(duì)應(yīng)的返回地址(運(yùn)行某函數(shù)時(shí),函數(shù)的返回地址最先進(jìn)棧)、函數(shù)涉及的局部變量、函數(shù)的參數(shù)值,也就是說(shuō),該函數(shù)的相關(guān)信息會(huì)占用棧的某一段空間。函數(shù)被壓進(jìn)棧后,可以通過(guò)當(dāng)前的棧幀地址獲取該函數(shù)所在棧中的首地址,其中,棧幀地址可以是該函數(shù)對(duì)應(yīng)的相關(guān)信息占用的棧的某一段空間的首地址。當(dāng)該函數(shù)運(yùn)行結(jié)束后,該函數(shù)對(duì)應(yīng)的相關(guān)信息即會(huì)出棧。從而,可以獲取目標(biāo)程序的棧中當(dāng)前記錄的返回地址,并確定每個(gè)返回地址在棧中的排列順序。獲取目標(biāo)程序的棧中當(dāng)前記錄的返回地址后,可以獲取本地存儲(chǔ)的目標(biāo)程序的指令地址與函數(shù)標(biāo)識(shí)的對(duì)應(yīng)關(guān)系,即指令地址對(duì)應(yīng)的代碼所屬的函數(shù)的對(duì)應(yīng)關(guān)系,并可以在目標(biāo)程序的指令地址與函數(shù)標(biāo)識(shí)的對(duì)應(yīng)關(guān)系中,獲取與返回地址相同的指令地址所對(duì)應(yīng)的函數(shù)標(biāo)識(shí),其中,被調(diào)用函數(shù)的返回地址即是調(diào)用函數(shù)的指令地址,得到每個(gè)返回地址對(duì)應(yīng)的函數(shù)標(biāo)識(shí)。得到每個(gè)返回地址對(duì)應(yīng)的函數(shù)標(biāo)識(shí)后,可以根據(jù)獲取的每個(gè)返回地址在棧中的排列順序,以及每個(gè)返回地址對(duì)應(yīng)的函數(shù)標(biāo)識(shí),確定動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù)當(dāng)前的各上級(jí)調(diào)用函數(shù)的調(diào)用關(guān)系。由于調(diào)用函數(shù)先入棧,被調(diào)用的函數(shù)后入棧,從而,可以根據(jù)獲取的每個(gè)返回地址在棧中的排列順序獲知函數(shù)的調(diào)用關(guān)系。
可選的,所述處理器110,還用于:
在每個(gè)返回地址對(duì)應(yīng)的函數(shù)標(biāo)識(shí)中,確定滿足預(yù)設(shè)過(guò)濾條件的函數(shù)標(biāo)識(shí),選取所述滿足預(yù)設(shè)過(guò)濾條件的函數(shù)標(biāo)識(shí)對(duì)應(yīng)的返回地址;
所述處理器110,具體用于:
根據(jù)選取的返回地址在所述棧中的排列順序,以及所述滿足預(yù)設(shè)過(guò)濾條件的函數(shù)標(biāo)識(shí),確定所述動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù)當(dāng)前的各上級(jí)調(diào)用函數(shù)的調(diào)用關(guān)系。
在實(shí)施中,可以預(yù)先設(shè)置過(guò)濾條件(可以稱為預(yù)設(shè)過(guò)濾條件)并存儲(chǔ),其中,可以通過(guò)預(yù)設(shè)過(guò)濾條件將c標(biāo)準(zhǔn)函數(shù)或者已經(jīng)確定不會(huì)發(fā)生內(nèi)存泄露的函數(shù)過(guò)濾掉。得到目標(biāo)程序的棧中當(dāng)前記錄的返回地址對(duì)應(yīng)的函數(shù)標(biāo)識(shí)后,處理器110可以判斷對(duì)應(yīng)的函數(shù)標(biāo)識(shí)是否滿足預(yù)設(shè)過(guò)濾條件,可以在獲取的所有的函數(shù)標(biāo)識(shí)中選取滿足預(yù)設(shè)過(guò)濾條件的函數(shù)標(biāo)識(shí),進(jìn)而可以根據(jù)得到的每個(gè)返回地址與函數(shù)標(biāo)識(shí)的對(duì)應(yīng)關(guān)系,選取滿足預(yù)設(shè)過(guò)濾條件的函數(shù)標(biāo)識(shí)對(duì)應(yīng)的返回地址。過(guò)濾掉一般部分函數(shù)標(biāo)識(shí)后,可以根據(jù)剩余的返回地址在棧中的排列順序,以及剩余的返回地址對(duì)應(yīng)的函數(shù)標(biāo)識(shí),確定動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù)當(dāng)前的各上級(jí)調(diào)用函數(shù)的調(diào)用關(guān)系。這樣,存儲(chǔ)的信息相對(duì)來(lái)講將會(huì)減少,從而,可以節(jié)約存儲(chǔ)空間,以及可以提高確定發(fā)生內(nèi)存泄露的位置的效率。
可選的,所述處理器110,還用于:
當(dāng)檢測(cè)到所述內(nèi)存地址對(duì)應(yīng)的內(nèi)存被釋放時(shí),從所述內(nèi)存占用數(shù)據(jù)庫(kù)中刪除所述內(nèi)存地址所屬的對(duì)應(yīng)關(guān)系。
在實(shí)施中,在目標(biāo)程序執(zhí)行過(guò)程中,處理器110每當(dāng)檢測(cè)到內(nèi)存釋放函數(shù)被調(diào)用時(shí),其中,內(nèi)存釋放函數(shù)可以用于對(duì)通過(guò)動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù)申請(qǐng)到的內(nèi)存進(jìn)行釋放,即檢測(cè)到內(nèi)存地址對(duì)應(yīng)的內(nèi)存被釋放時(shí),可以從內(nèi)存數(shù)據(jù)庫(kù)中刪除內(nèi)存地址所屬的對(duì)應(yīng)關(guān)系。
可選的,所述處理器110,具體用于:
在目標(biāo)程序執(zhí)行過(guò)程中,當(dāng)檢測(cè)到所述動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù)的調(diào)用指令時(shí),執(zhí)行預(yù)設(shè)動(dòng)態(tài)鏈接庫(kù)中的程序,以執(zhí)行所述動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù),獲取通過(guò)所述動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù)申請(qǐng)到的內(nèi)存地址,并獲取所述調(diào)用指令的各上級(jí)調(diào)用函數(shù)的調(diào)用關(guān)系,在內(nèi)存占用數(shù)據(jù)庫(kù)中,記錄所述內(nèi)存地址與所述調(diào)用關(guān)系的對(duì)應(yīng)關(guān)系;
當(dāng)檢測(cè)到對(duì)所述內(nèi)存地址對(duì)應(yīng)的內(nèi)存的釋放指令時(shí),執(zhí)行所述預(yù)設(shè)動(dòng)態(tài)鏈接庫(kù)中的程序,釋放所述內(nèi)存,并從所述內(nèi)存占用數(shù)據(jù)庫(kù)中刪除所述內(nèi)存地址所屬的對(duì)應(yīng)關(guān)系。
在實(shí)施中,可以預(yù)先設(shè)置動(dòng)態(tài)鏈接庫(kù)(可以稱為預(yù)設(shè)動(dòng)態(tài)鏈接庫(kù)),在目標(biāo)程序執(zhí)行過(guò)程中,處理器110當(dāng)檢測(cè)到動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù)的調(diào)用指令時(shí),可以 執(zhí)行預(yù)設(shè)動(dòng)態(tài)鏈接庫(kù)中的程序,以便執(zhí)行動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù),此時(shí),預(yù)設(shè)動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù)中的程序相當(dāng)于是動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù)的具體代碼,當(dāng)預(yù)設(shè)動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù)中的程序全部執(zhí)行完畢時(shí),即相當(dāng)于動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù)執(zhí)行完畢。具體的,執(zhí)行預(yù)設(shè)動(dòng)態(tài)鏈接庫(kù)中的程序,可以獲取通過(guò)動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù)申請(qǐng)到的內(nèi)存地址,并獲取調(diào)用指令的各上級(jí)調(diào)用函數(shù)的調(diào)用關(guān)系,即獲取目標(biāo)程序中調(diào)用動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù)的各上級(jí)調(diào)用函數(shù)的調(diào)用關(guān)系,并可以在內(nèi)存占用數(shù)據(jù)庫(kù)中,記錄內(nèi)存地址與調(diào)用關(guān)系的對(duì)應(yīng)關(guān)系。
針對(duì)刪除內(nèi)存地址所屬的對(duì)應(yīng)關(guān)系的情況,在目標(biāo)程序的執(zhí)行過(guò)程中,處理器110當(dāng)檢測(cè)到對(duì)內(nèi)存地址對(duì)應(yīng)的內(nèi)存的釋放指令時(shí),也可以執(zhí)行預(yù)設(shè)動(dòng)態(tài)鏈接庫(kù)中的程序,對(duì)內(nèi)存地址對(duì)應(yīng)的內(nèi)存進(jìn)行釋放,并可以從內(nèi)存占用數(shù)據(jù)庫(kù)中刪除內(nèi)存地址所屬的對(duì)應(yīng)關(guān)系。
這樣,無(wú)需修改目標(biāo)程序,通過(guò)執(zhí)行預(yù)設(shè)動(dòng)態(tài)鏈接庫(kù)中的程序即可獲取目標(biāo)程序通過(guò)動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù)申請(qǐng)到的內(nèi)存地址,以及對(duì)應(yīng)的各上級(jí)調(diào)用函數(shù)的調(diào)用關(guān)系,另外,利用此種方式,若目標(biāo)程序無(wú)法修改時(shí),其中,當(dāng)目標(biāo)程序是標(biāo)準(zhǔn)c函數(shù)或者第三方程序時(shí),技術(shù)人員無(wú)法對(duì)源代碼進(jìn)行修改,也可以通過(guò)執(zhí)行預(yù)設(shè)動(dòng)態(tài)鏈接庫(kù)中的程序獲取相關(guān)的信息,以便進(jìn)行后續(xù)確定發(fā)生內(nèi)存泄露的位置的相關(guān)處理。
可選的,所述處理器110,具體用于:
確定每個(gè)調(diào)用關(guān)系對(duì)應(yīng)的內(nèi)存申請(qǐng)次數(shù)和內(nèi)存釋放次數(shù),確定所述每個(gè)調(diào)用關(guān)系對(duì)應(yīng)的內(nèi)存申請(qǐng)次數(shù)和內(nèi)存釋放次數(shù)的差值;
在所述每個(gè)調(diào)用關(guān)系對(duì)應(yīng)的內(nèi)存申請(qǐng)次數(shù)和內(nèi)存釋放次數(shù)的差值中,確定滿足預(yù)設(shè)選取條件的差值,選取滿足預(yù)設(shè)選取條件的差值對(duì)應(yīng)的目標(biāo)調(diào)用關(guān)系;
將所述目標(biāo)調(diào)用關(guān)系對(duì)應(yīng)的程序位置確定為發(fā)生內(nèi)存泄露的位置。
在實(shí)施中,可以預(yù)先設(shè)置差值獲取觸發(fā)事件,其中,差值獲取觸發(fā)事件可以是達(dá)到預(yù)設(shè)的差值獲取周期,也可以是檢測(cè)到存儲(chǔ)內(nèi)存地址與調(diào)用關(guān)系的對(duì)應(yīng)關(guān)系,每當(dāng)檢測(cè)到預(yù)設(shè)的差值獲取觸發(fā)事件發(fā)生時(shí),可以確定已經(jīng)存儲(chǔ)的每個(gè)調(diào)用關(guān)系對(duì)應(yīng)的內(nèi)存申請(qǐng)次數(shù)和內(nèi)存釋放次數(shù),確定每個(gè)調(diào)用關(guān)系對(duì)應(yīng)的內(nèi)存申請(qǐng)次數(shù)和內(nèi)存釋放次數(shù)的差值。之后,可以在每個(gè)調(diào)用關(guān)系對(duì)應(yīng)的內(nèi)存申請(qǐng)次數(shù)和內(nèi)存釋放次數(shù)的差值中,確定滿足預(yù)設(shè)選取條件的差值,并且可以選取滿足預(yù)設(shè)選取條件的差值對(duì)應(yīng)的目標(biāo)調(diào)用關(guān)系,進(jìn)而,可以將目標(biāo)調(diào)用關(guān)系 對(duì)應(yīng)的程序位置確定為發(fā)生內(nèi)存泄露的位置,即可以將目標(biāo)程序中出現(xiàn)目標(biāo)調(diào)用關(guān)系的代碼位置確定為發(fā)生內(nèi)存泄露的位置。
可選的,所述處理器110,具體用于:
在所述每個(gè)調(diào)用關(guān)系對(duì)應(yīng)的內(nèi)存申請(qǐng)次數(shù)和內(nèi)存釋放次數(shù)的差值中,獲取預(yù)設(shè)數(shù)目個(gè)最大的差值,并確定所述預(yù)設(shè)數(shù)目個(gè)最大的差值對(duì)應(yīng)的目標(biāo)調(diào)用關(guān)系。
在實(shí)施中,確定出每個(gè)調(diào)用關(guān)系對(duì)應(yīng)的內(nèi)存申請(qǐng)次數(shù)和內(nèi)存釋放次數(shù)的差值后,可以按照差值由大到小的順序,對(duì)其進(jìn)行排序,可以從中獲取排在前列的預(yù)設(shè)數(shù)目個(gè)差值對(duì)應(yīng)的目標(biāo)調(diào)用關(guān)系。
本發(fā)明實(shí)施例中,在目標(biāo)程序執(zhí)行過(guò)程中,當(dāng)檢測(cè)到動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù)被調(diào)用時(shí),獲取通過(guò)動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù)申請(qǐng)到的內(nèi)存地址,并獲取動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù)當(dāng)前的各上級(jí)調(diào)用函數(shù)的調(diào)用關(guān)系,在內(nèi)存占用數(shù)據(jù)庫(kù)中,記錄內(nèi)存地址與調(diào)用關(guān)系的對(duì)應(yīng)關(guān)系,根據(jù)記錄的調(diào)用關(guān)系,確定發(fā)生內(nèi)存泄露的位置。這樣,在目標(biāo)程序執(zhí)行過(guò)程中,可以通過(guò)記錄的調(diào)用關(guān)系,縮小查找的范圍,在目標(biāo)程序中快速找到發(fā)生內(nèi)存泄露的代碼位置,從而,可以提高查找內(nèi)存泄露的代碼位置的效率。
基于相同的構(gòu)思,本實(shí)施例還提供了一種確定內(nèi)存泄露位置的裝置,如圖5所示,該裝置可以實(shí)現(xiàn)步驟201-202,301-303所述的方法,包括:
獲取模塊510,具體可以由處理器實(shí)現(xiàn),用于在目標(biāo)程序執(zhí)行過(guò)程中,當(dāng)檢測(cè)到動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù)被調(diào)用時(shí),獲取通過(guò)所述動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù)申請(qǐng)到的內(nèi)存地址,并獲取所述動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù)當(dāng)前的各上級(jí)調(diào)用函數(shù)的調(diào)用關(guān)系,在內(nèi)存占用數(shù)據(jù)庫(kù)中,記錄所述內(nèi)存地址與所述調(diào)用關(guān)系的對(duì)應(yīng)關(guān)系;
確定模塊520,具體可以由處理器實(shí)現(xiàn),用于根據(jù)所述獲取模塊510記錄的調(diào)用關(guān)系,確定發(fā)生內(nèi)存泄露的位置。
在實(shí)施中,在目標(biāo)程序執(zhí)行過(guò)程中,每當(dāng)檢測(cè)到動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù)被調(diào)用時(shí),其中,動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù)可以用于動(dòng)態(tài)申請(qǐng)系統(tǒng)中的內(nèi)存,可以根據(jù)函數(shù)的參數(shù)值申請(qǐng)指定大小的內(nèi)存,并且該函數(shù)可以返回申請(qǐng)到的內(nèi)存的首地址(可以稱為內(nèi)存地址),獲取模塊510可以獲取通過(guò)動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù)申請(qǐng)到的內(nèi)存地址,并可以獲取調(diào)用該動(dòng)態(tài)申請(qǐng)函數(shù)的各函數(shù)嵌套關(guān)系,即可以獲取動(dòng)態(tài)內(nèi) 存申請(qǐng)函數(shù)當(dāng)前的各上級(jí)調(diào)用函數(shù)的調(diào)用關(guān)系,并對(duì)其進(jìn)行存儲(chǔ),獲取內(nèi)存地址以及上述調(diào)用關(guān)系后,可以記錄之間的對(duì)應(yīng)關(guān)系,并存儲(chǔ)在內(nèi)存占用數(shù)據(jù)庫(kù)中,其中,該內(nèi)存占用數(shù)據(jù)庫(kù)可以是內(nèi)存占用表,也可以是內(nèi)存占用樹(shù),即可以將內(nèi)存地址與上述調(diào)用關(guān)系的對(duì)應(yīng)關(guān)系存儲(chǔ)在表中,也可以存儲(chǔ)在樹(shù)中,比如可以是紅黑樹(shù)。在目標(biāo)程序執(zhí)行過(guò)程中,每獲取到動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù)當(dāng)前的各上級(jí)調(diào)用函數(shù)的調(diào)用關(guān)系時(shí),可以存儲(chǔ)調(diào)用關(guān)系對(duì)應(yīng)的內(nèi)存申請(qǐng)次數(shù)和內(nèi)存釋放次數(shù)。獲取到內(nèi)存地址對(duì)應(yīng)的調(diào)用關(guān)系后,確定模塊520可以根據(jù)記錄的調(diào)用關(guān)系,確定發(fā)生內(nèi)存泄露的位置,具體的,計(jì)算設(shè)備還可以在獲取到通過(guò)動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù)申請(qǐng)到的內(nèi)存地址后,獲取該內(nèi)存地址對(duì)應(yīng)的申請(qǐng)時(shí)間點(diǎn),此種情況下,可以確定申請(qǐng)時(shí)間點(diǎn)距離當(dāng)前時(shí)間點(diǎn)的時(shí)長(zhǎng)大于預(yù)設(shè)時(shí)長(zhǎng)的內(nèi)存地址,并確定該內(nèi)存地址對(duì)應(yīng)的調(diào)用關(guān)系,進(jìn)而,可以根據(jù)確定出的申請(qǐng)時(shí)間點(diǎn)距離當(dāng)前時(shí)間點(diǎn)的時(shí)長(zhǎng)大于預(yù)設(shè)時(shí)長(zhǎng)的內(nèi)存地址對(duì)應(yīng)的調(diào)用關(guān)系,確定發(fā)生內(nèi)存泄露的位置。
可選的,所述獲取模塊510,還用于:
當(dāng)檢測(cè)到動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù)被調(diào)用時(shí),獲取調(diào)用所述動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù)的代碼行標(biāo)識(shí);
所述獲取模塊510,具體用于:
在內(nèi)存占用數(shù)據(jù)庫(kù)中,記錄所述內(nèi)存地址與所述代碼行標(biāo)識(shí)、所述調(diào)用關(guān)系的對(duì)應(yīng)關(guān)系。
在實(shí)施中,在目標(biāo)程序的執(zhí)行過(guò)程中,當(dāng)檢測(cè)到動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù)被調(diào)用時(shí),獲取模塊510還可以獲取調(diào)用動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù)的指令地址,進(jìn)而,可以根據(jù)指令地址與代碼位置的對(duì)應(yīng)關(guān)系,確定動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù)在調(diào)用動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù)中的代碼位置,即檢測(cè)到動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù)被調(diào)用時(shí),獲取調(diào)用動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù)的代碼行標(biāo)識(shí),其中,代碼行標(biāo)識(shí)可以是代碼在調(diào)用函數(shù)中的行號(hào)。此種情況下,可以在內(nèi)存占用數(shù)據(jù)庫(kù)中,記錄內(nèi)存地址與代碼行標(biāo)識(shí)、調(diào)用關(guān)系的對(duì)應(yīng)關(guān)系。
可選的,所述獲取模塊510,具體用于:
獲取所述目標(biāo)程序的棧中當(dāng)前記錄的返回地址,并確定每個(gè)返回地址在所述棧中的排列順序;
所述確定模塊520,具體用于:
根據(jù)所述目標(biāo)程序的指令地址與函數(shù)標(biāo)識(shí)的對(duì)應(yīng)關(guān)系,分別確定與每個(gè)返回地址相同的指令地址所對(duì)應(yīng)的函數(shù)標(biāo)識(shí),得到每個(gè)返回地址對(duì)應(yīng)的函數(shù)標(biāo)識(shí);
根據(jù)所述每個(gè)返回地址在所述棧中的排列順序,以及每個(gè)返回地址對(duì)應(yīng)的函數(shù)標(biāo)識(shí),確定所述動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù)當(dāng)前的各上級(jí)調(diào)用函數(shù)的調(diào)用關(guān)系。
在實(shí)施中,在運(yùn)行目標(biāo)程序中的函數(shù)時(shí),會(huì)將函數(shù)的相關(guān)信息壓進(jìn)目標(biāo)程序的棧中,其中,函數(shù)的相關(guān)信息可以是函數(shù)對(duì)應(yīng)的返回地址(運(yùn)行某函數(shù)時(shí),函數(shù)的返回地址最先進(jìn)棧)、函數(shù)涉及的局部變量、函數(shù)的參數(shù)值,也就是說(shuō),該函數(shù)的相關(guān)信息會(huì)占用棧的某一段空間。函數(shù)被壓進(jìn)棧后,獲取模塊510可以通過(guò)當(dāng)前的棧幀地址獲取該函數(shù)所在棧中的首地址,其中,棧幀地址可以是該函數(shù)對(duì)應(yīng)的相關(guān)信息占用的棧的某一段空間的首地址。當(dāng)該函數(shù)運(yùn)行結(jié)束后,該函數(shù)對(duì)應(yīng)的相關(guān)信息即會(huì)出棧。從而,可以獲取目標(biāo)程序的棧中當(dāng)前記錄的返回地址,并確定每個(gè)返回地址在棧中的排列順序。獲取目標(biāo)程序的棧中當(dāng)前記錄的返回地址后,可以獲取本地存儲(chǔ)的目標(biāo)程序的指令地址與函數(shù)標(biāo)識(shí)的對(duì)應(yīng)關(guān)系,即指令地址對(duì)應(yīng)的代碼所屬的函數(shù)的對(duì)應(yīng)關(guān)系,并可以在目標(biāo)程序的指令地址與函數(shù)標(biāo)識(shí)的對(duì)應(yīng)關(guān)系中,獲取與返回地址相同的指令地址所對(duì)應(yīng)的函數(shù)標(biāo)識(shí),其中,被調(diào)用函數(shù)的返回地址即是調(diào)用函數(shù)的指令地址,得到每個(gè)返回地址對(duì)應(yīng)的函數(shù)標(biāo)識(shí)。得到每個(gè)返回地址對(duì)應(yīng)的函數(shù)標(biāo)識(shí)后,確定模塊520可以根據(jù)獲取的每個(gè)返回地址在棧中的排列順序,以及每個(gè)返回地址對(duì)應(yīng)的函數(shù)標(biāo)識(shí),確定動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù)當(dāng)前的各上級(jí)調(diào)用函數(shù)的調(diào)用關(guān)系。由于調(diào)用函數(shù)先入棧,被調(diào)用的函數(shù)后入棧,從而,可以根據(jù)獲取的每個(gè)返回地址在棧中的排列順序獲知函數(shù)的調(diào)用關(guān)系。
可選的,所述確定模塊520,還用于:
在每個(gè)返回地址對(duì)應(yīng)的函數(shù)標(biāo)識(shí)中,確定滿足預(yù)設(shè)過(guò)濾條件的函數(shù)標(biāo)識(shí),選取所述滿足預(yù)設(shè)過(guò)濾條件的函數(shù)標(biāo)識(shí)對(duì)應(yīng)的返回地址;
所述確定模塊520,具體用于:
根據(jù)選取的返回地址在所述棧中的排列順序,以及所述滿足預(yù)設(shè)過(guò)濾條件的函數(shù)標(biāo)識(shí),確定所述動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù)當(dāng)前的各上級(jí)調(diào)用函數(shù)的調(diào)用關(guān)系。
在實(shí)施中,可以預(yù)先設(shè)置過(guò)濾條件(可以稱為預(yù)設(shè)過(guò)濾條件)并存儲(chǔ),其中,可以通過(guò)預(yù)設(shè)過(guò)濾條件將c標(biāo)準(zhǔn)函數(shù)或者已經(jīng)確定不會(huì)發(fā)生內(nèi)存泄露的函數(shù)過(guò)濾掉。得到目標(biāo)程序的棧中當(dāng)前記錄的返回地址對(duì)應(yīng)的函數(shù)標(biāo)識(shí)后,確定 模塊520可以判斷對(duì)應(yīng)的函數(shù)標(biāo)識(shí)是否滿足預(yù)設(shè)過(guò)濾條件,可以在獲取的所有的函數(shù)標(biāo)識(shí)中選取滿足預(yù)設(shè)過(guò)濾條件的函數(shù)標(biāo)識(shí),進(jìn)而可以根據(jù)得到的每個(gè)返回地址與函數(shù)標(biāo)識(shí)的對(duì)應(yīng)關(guān)系,選取滿足預(yù)設(shè)過(guò)濾條件的函數(shù)標(biāo)識(shí)對(duì)應(yīng)的返回地址。過(guò)濾掉一般部分函數(shù)標(biāo)識(shí)后,確定模塊520可以根據(jù)剩余的返回地址在棧中的排列順序,以及剩余的返回地址對(duì)應(yīng)的函數(shù)標(biāo)識(shí),確定動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù)當(dāng)前的各上級(jí)調(diào)用函數(shù)的調(diào)用關(guān)系。
可選的,如圖6所示,還包括:
刪除模塊530,用于當(dāng)檢測(cè)到所述內(nèi)存地址對(duì)應(yīng)的內(nèi)存被釋放時(shí),從所述內(nèi)存占用數(shù)據(jù)庫(kù)中刪除所述內(nèi)存地址所屬的對(duì)應(yīng)關(guān)系。
在實(shí)施中,在目標(biāo)程序執(zhí)行過(guò)程中,每當(dāng)檢測(cè)到內(nèi)存釋放函數(shù)被調(diào)用時(shí),其中,內(nèi)存釋放函數(shù)可以用于對(duì)通過(guò)動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù)申請(qǐng)到的內(nèi)存進(jìn)行釋放,即檢測(cè)到內(nèi)存地址對(duì)應(yīng)的內(nèi)存被釋放時(shí),刪除模塊530可以從內(nèi)存數(shù)據(jù)庫(kù)中刪除內(nèi)存地址所屬的對(duì)應(yīng)關(guān)系。
可選的,所述獲取模塊510,具體用于:
在目標(biāo)程序執(zhí)行過(guò)程中,當(dāng)檢測(cè)到所述動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù)的調(diào)用指令時(shí),執(zhí)行預(yù)設(shè)動(dòng)態(tài)鏈接庫(kù)中的程序,以執(zhí)行所述動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù),獲取通過(guò)所述動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù)申請(qǐng)到的內(nèi)存地址,并獲取所述調(diào)用指令的各上級(jí)調(diào)用函數(shù)的調(diào)用關(guān)系,在內(nèi)存占用數(shù)據(jù)庫(kù)中,記錄所述內(nèi)存地址與所述調(diào)用關(guān)系的對(duì)應(yīng)關(guān)系;
所述刪除模塊530,具體用于:
當(dāng)檢測(cè)到對(duì)所述內(nèi)存地址對(duì)應(yīng)的內(nèi)存的釋放指令時(shí),執(zhí)行所述預(yù)設(shè)動(dòng)態(tài)鏈接庫(kù)中的程序,釋放所述內(nèi)存,并從所述內(nèi)存占用數(shù)據(jù)庫(kù)中刪除所述內(nèi)存地址所屬的對(duì)應(yīng)關(guān)系。
在實(shí)施中,可以預(yù)先設(shè)置動(dòng)態(tài)鏈接庫(kù)(可以稱為預(yù)設(shè)動(dòng)態(tài)鏈接庫(kù)),在目標(biāo)程序執(zhí)行過(guò)程中,獲取模塊510當(dāng)檢測(cè)到動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù)的調(diào)用指令時(shí),可以執(zhí)行預(yù)設(shè)動(dòng)態(tài)鏈接庫(kù)中的程序,以便執(zhí)行動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù),此時(shí),預(yù)設(shè)動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù)中的程序相當(dāng)于是動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù)的具體代碼,當(dāng)預(yù)設(shè)動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù)中的程序全部執(zhí)行完畢時(shí),即相當(dāng)于動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù)執(zhí)行完畢。具體的,執(zhí)行預(yù)設(shè)動(dòng)態(tài)鏈接庫(kù)中的程序,可以獲取通過(guò)動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù)申請(qǐng)到的內(nèi)存地址,并獲取調(diào)用指令的各上級(jí)調(diào)用函數(shù)的調(diào)用關(guān)系,即獲取目標(biāo)程 序中調(diào)用動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù)的各上級(jí)調(diào)用函數(shù)的調(diào)用關(guān)系,并可以在內(nèi)存占用數(shù)據(jù)庫(kù)中,記錄內(nèi)存地址與調(diào)用關(guān)系的對(duì)應(yīng)關(guān)系。
針對(duì)刪除內(nèi)存地址所屬的對(duì)應(yīng)關(guān)系的情況,在目標(biāo)程序的執(zhí)行過(guò)程中,刪除模塊530當(dāng)檢測(cè)到對(duì)內(nèi)存地址對(duì)應(yīng)的內(nèi)存的釋放指令時(shí),也可以執(zhí)行預(yù)設(shè)動(dòng)態(tài)鏈接庫(kù)中的程序,對(duì)內(nèi)存地址對(duì)應(yīng)的內(nèi)存進(jìn)行釋放,并可以從內(nèi)存占用數(shù)據(jù)庫(kù)中刪除內(nèi)存地址所屬的對(duì)應(yīng)關(guān)系。
可選的,所述確定模塊520,具體用于:
確定每個(gè)調(diào)用關(guān)系對(duì)應(yīng)的內(nèi)存申請(qǐng)次數(shù)和內(nèi)存釋放次數(shù),確定所述每個(gè)調(diào)用關(guān)系對(duì)應(yīng)的內(nèi)存申請(qǐng)次數(shù)和內(nèi)存釋放次數(shù)的差值;
在所述每個(gè)調(diào)用關(guān)系對(duì)應(yīng)的內(nèi)存申請(qǐng)次數(shù)和內(nèi)存釋放次數(shù)的差值中,確定滿足預(yù)設(shè)選取條件的差值,選取滿足預(yù)設(shè)選取條件的差值對(duì)應(yīng)的目標(biāo)調(diào)用關(guān)系;
將所述目標(biāo)調(diào)用關(guān)系對(duì)應(yīng)的程序位置確定為發(fā)生內(nèi)存泄露的位置。
在實(shí)施中,可以預(yù)先設(shè)置差值獲取觸發(fā)事件,其中,差值獲取觸發(fā)事件可以是達(dá)到預(yù)設(shè)的差值獲取周期,也可以是檢測(cè)到存儲(chǔ)內(nèi)存地址與調(diào)用關(guān)系的對(duì)應(yīng)關(guān)系,每當(dāng)檢測(cè)到預(yù)設(shè)的差值獲取觸發(fā)事件發(fā)生時(shí),可以確定已經(jīng)存儲(chǔ)的每個(gè)調(diào)用關(guān)系對(duì)應(yīng)的內(nèi)存申請(qǐng)次數(shù)和內(nèi)存釋放次數(shù),確定每個(gè)調(diào)用關(guān)系對(duì)應(yīng)的內(nèi)存申請(qǐng)次數(shù)和內(nèi)存釋放次數(shù)的差值。之后,可以在每個(gè)調(diào)用關(guān)系對(duì)應(yīng)的內(nèi)存申請(qǐng)次數(shù)和內(nèi)存釋放次數(shù)的差值中,確定滿足預(yù)設(shè)選取條件的差值,并且可以選取滿足預(yù)設(shè)選取條件的差值對(duì)應(yīng)的目標(biāo)調(diào)用關(guān)系,進(jìn)而,可以將目標(biāo)調(diào)用關(guān)系對(duì)應(yīng)的程序位置確定為發(fā)生內(nèi)存泄露的位置,即可以將目標(biāo)程序中出現(xiàn)目標(biāo)調(diào)用關(guān)系的代碼位置確定為發(fā)生內(nèi)存泄露的位置。
可選的,所述確定模塊520,具體用于:
在所述每個(gè)調(diào)用關(guān)系對(duì)應(yīng)的內(nèi)存申請(qǐng)次數(shù)和內(nèi)存釋放次數(shù)的差值中,獲取預(yù)設(shè)數(shù)目個(gè)最大的差值,并確定所述預(yù)設(shè)數(shù)目個(gè)最大的差值對(duì)應(yīng)的目標(biāo)調(diào)用關(guān)系。
在實(shí)施中,確定出每個(gè)調(diào)用關(guān)系對(duì)應(yīng)的內(nèi)存申請(qǐng)次數(shù)和內(nèi)存釋放次數(shù)的差值后,可以按照差值由大到小的順序,對(duì)其進(jìn)行排序,可以從中獲取排在前列的預(yù)設(shè)數(shù)目個(gè)差值對(duì)應(yīng)的目標(biāo)調(diào)用關(guān)系。
本發(fā)明實(shí)施例中,在目標(biāo)程序執(zhí)行過(guò)程中,當(dāng)檢測(cè)到動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù)被調(diào)用時(shí),獲取通過(guò)動(dòng)態(tài)內(nèi)存申請(qǐng)函數(shù)申請(qǐng)到的內(nèi)存地址,并獲取動(dòng)態(tài)內(nèi)存申請(qǐng) 函數(shù)當(dāng)前的各上級(jí)調(diào)用函數(shù)的調(diào)用關(guān)系,在內(nèi)存占用數(shù)據(jù)庫(kù)中,記錄內(nèi)存地址與調(diào)用關(guān)系的對(duì)應(yīng)關(guān)系,根據(jù)記錄的調(diào)用關(guān)系,確定發(fā)生內(nèi)存泄露的位置。這樣,在目標(biāo)程序執(zhí)行過(guò)程中,可以通過(guò)記錄的調(diào)用關(guān)系,縮小查找的范圍,在目標(biāo)程序中快速找到發(fā)生內(nèi)存泄露的代碼位置,從而,可以提高查找內(nèi)存泄露的代碼位置的效率。
需要說(shuō)明的是:上述實(shí)施例提供的確定內(nèi)存泄露位置的裝置在確定內(nèi)存泄露位置時(shí),僅以上述各功能模塊的劃分進(jìn)行舉例說(shuō)明,實(shí)際應(yīng)用中,可以根據(jù)需要而將上述功能分配由不同的功能模塊完成,即將計(jì)算設(shè)備的內(nèi)部結(jié)構(gòu)劃分成不同的功能模塊,以完成以上描述的全部或者部分功能。另外,上述實(shí)施例提供的確定內(nèi)存泄露位置的裝置與確定內(nèi)存泄露位置的方法實(shí)施例屬于同一構(gòu)思,其具體實(shí)現(xiàn)過(guò)程詳見(jiàn)方法實(shí)施例,這里不再贅述。
本領(lǐng)域普通技術(shù)人員可以理解實(shí)現(xiàn)上述實(shí)施例的全部或部分步驟可以通過(guò)硬件來(lái)完成,也可以通過(guò)程序來(lái)指令相關(guān)的硬件完成,所述的程序可以存儲(chǔ)于一種計(jì)算機(jī)可讀存儲(chǔ)介質(zhì)中,上述提到的存儲(chǔ)介質(zhì)可以是只讀存儲(chǔ)器,磁盤或光盤等。
以上所述僅為本發(fā)明的較佳實(shí)施例,并不用以限制本發(fā)明,凡在本發(fā)明的精神和原則之內(nèi),所作的任何修改、等同替換、改進(jìn)等,均應(yīng)包含在本發(fā)明的保護(hù)范圍之內(nèi)。