專利名稱:一種檢測內(nèi)存訪問越界的方法
技術(shù)領(lǐng)域:
本發(fā)明涉及一種檢測內(nèi)存訪問越界的方法,具體地說,尤指嵌入式實(shí) 時(shí)系統(tǒng)中檢測應(yīng)用程序在使用所申請的內(nèi)存塊的過程中是否存在內(nèi)存寫 入越界的情況,并提示相關(guān)的異常信息。
背景技術(shù):
在嵌入式實(shí)時(shí)系統(tǒng)中,應(yīng)用程序?qū)?nèi)存的使用頻率相當(dāng)高,尤其是需 要頻繁地申請和釋放內(nèi)存。而嵌入式實(shí)時(shí)操作系統(tǒng)提供的動態(tài)內(nèi)存管理方 法是針對一般情況的,為應(yīng)用程序提供內(nèi)存申請和釋放的接口, 一方面, 調(diào)用這些接口的執(zhí)行效率比較低,另一方面,頻繁調(diào)用這些接口申請和釋 放內(nèi)存會形成過多的內(nèi)存碎片,不僅影響執(zhí)行效率,也造成內(nèi)存浪費(fèi)。
目前,在嵌入式實(shí)時(shí)系統(tǒng)中進(jìn)行應(yīng)用軟件開發(fā)時(shí),大多數(shù)情況下,會 在操作系統(tǒng)基礎(chǔ)上形成適合自身需求的內(nèi)存管理方法,對操作系統(tǒng)的內(nèi)存 管理接口進(jìn)行封裝,提供給應(yīng)用程序使用。這樣的內(nèi)存管理方法可能是多
種多樣的,但一般具有一些基本的共同特征首先通過一次或多次調(diào)用操 作系統(tǒng)的申請內(nèi)存接口創(chuàng)建一個(gè)內(nèi)存池,內(nèi)存池由各種固定大小的內(nèi)存塊 組成, 一般相同大小的內(nèi)存塊組成一個(gè)區(qū)域,通過鏈表或其它數(shù)據(jù)結(jié)構(gòu)來 維護(hù)內(nèi)存池;應(yīng)用程序申請內(nèi)存時(shí),給其分配一個(gè)不小于所申請大小的可 用內(nèi)存塊。所分配的內(nèi)存塊往往大于所申請大小,內(nèi)存塊中超出申請大小 的部分為空閑區(qū),應(yīng)用考呈序不應(yīng)該-沐問該區(qū)i或。
應(yīng)用程序申請到內(nèi)存塊后得到一個(gè)內(nèi)存指針,通過該指針可以對內(nèi)存 塊區(qū)域進(jìn)行讀寫操作。很多情況下,由于程序代碼編寫上的疏忽,會造成 內(nèi)存訪問越界問題,比如,寫入時(shí)超出了所申請內(nèi)存塊的地址范圍,覆蓋 了其它內(nèi)存區(qū)域,可能造成程序運(yùn)行異常。有時(shí),雖然沒有超出內(nèi)存塊的
地址范圍,但已超出了所申請大小,也就是覆蓋了內(nèi)存塊中的空閑區(qū),這 種情況不一定造成程序運(yùn)行異常,但同樣屬于程序代碼錯(cuò)誤,如不及時(shí)發(fā) 現(xiàn)也是程序運(yùn)行中的隱患。
現(xiàn)有技術(shù)中,為解決內(nèi)存訪問越界問題,試圖實(shí)時(shí)檢測出內(nèi)存訪問越 界情況,要求應(yīng)用程序的內(nèi)存訪問操作都通過專門封裝的接口進(jìn)行,在接 口中對訪問的內(nèi)存地址和范圍進(jìn)行檢查,進(jìn)而判斷是否存在訪問越界。優(yōu)
點(diǎn)是一定程度上能實(shí)時(shí)檢測出內(nèi)存越界情況,但是有如下缺點(diǎn)首先,應(yīng) 用程序?qū)?nèi)存的讀寫操作都需要通過封裝接口進(jìn)行,必然會大大降低系統(tǒng) 運(yùn)行效率,這對嵌入式實(shí)時(shí)系統(tǒng)來說是不可接受的;其次,應(yīng)用程序?qū)λ?申請內(nèi)存的使用方式是任意的,可以直接通過內(nèi)存指針訪問其中的地址, 也可以存放某種數(shù)據(jù)結(jié)構(gòu)的數(shù)據(jù),如果全部需要通過封裝接口進(jìn)行,會給 程序代碼的編寫造成極大的不便;最后,實(shí)現(xiàn)這種內(nèi)存檢測方法需要提供 專門的內(nèi)存管理方法,不能將其方便地應(yīng)用到其它內(nèi)存管理方法中。
發(fā)明內(nèi)容
本發(fā)明所要解決的技術(shù)問題在于提供一種檢測內(nèi)存訪問越界的方法,
以解決內(nèi)存訪問越界問題,尤指嵌入式實(shí)時(shí)系統(tǒng)中檢測應(yīng)用程序在使用所
申請的內(nèi)存塊的過程中是否存在內(nèi)存寫入越界的情況,并提示相關(guān)的異常 狀臺
為了解決上述問題,本發(fā)明提供了一種檢測內(nèi)存訪問越界的方法,在 應(yīng)用程序使用從內(nèi)存池中申請的內(nèi)存塊的過程中,檢測是否存在內(nèi)存寫入 越界的情況,其包括如下步驟
(1) 創(chuàng)建內(nèi)存池時(shí),如杲初始化一個(gè)可用空間大小為Size的內(nèi)存塊, 則需要為其分配的全部內(nèi)存空間為可用空間大小Size加上需要為該內(nèi)存 塊添加的前端信息和尾端信息所占空間大小之和,其中,所述尾端信息包 括保護(hù)字信息、空閑區(qū)長度信息;
(2) 應(yīng)用程序申請內(nèi)存時(shí),如果為其找到一個(gè)合適的內(nèi)存塊,則將 所述內(nèi)存塊的尾端信息中的保護(hù)字設(shè)定為保護(hù)標(biāo)記,將空閑區(qū)長度設(shè)定為
內(nèi)存塊大小Size減去用戶申請大小的值,如果空閑區(qū)長度不為零,則在 從所述空閑區(qū)起始地址開始,在預(yù)設(shè)區(qū)域填充保護(hù)標(biāo)記;
(3) 應(yīng)用程序釋放內(nèi)存時(shí),檢測尾端信息中的保護(hù)字是否為設(shè)定的 保護(hù)標(biāo)記,如果不是,則提示內(nèi)存訪問越界的異常信息;如果保護(hù)字是設(shè) 定的保護(hù)標(biāo)記,則檢測空閑區(qū)中已填充保護(hù)標(biāo)記的區(qū)域,當(dāng)發(fā)現(xiàn)某處不是 設(shè)定的保護(hù)標(biāo)記時(shí),提示內(nèi)存訪問越界的異常信息。
進(jìn)一步地,本發(fā)明所述的方法,其步驟(l)中進(jìn)一步包括所述前 端信息包括頭部信息、申請代碼地址信息,所述內(nèi)存塊可用空間在實(shí)際使 用時(shí)分為用戶數(shù)據(jù)區(qū)與空閑區(qū);
步驟(2)中進(jìn)一步包括所述內(nèi)存塊的前端信息中填寫頭部信息, 并將申請代碼地址設(shè)定為所獲得的調(diào)用申請內(nèi)存接口的代碼地址;
步驟(3)中進(jìn)一步包括所述提示內(nèi)存訪問越界的異常信息中包括 申請代碼地址信息。
進(jìn)一步地,其所述步驟(2)中,如果應(yīng)用程序只有一個(gè)代碼段,則 在申請代碼地址信息中只需記錄偏移地址;如杲應(yīng)用程序包舍多個(gè)代碼 段,則在申請代碼地址信息中進(jìn)一步記錄代碼的段地址。
進(jìn)一步地,本發(fā)明所述的方法,其所述步驟(2)中,尾端信息中的 保護(hù)字設(shè)定的保護(hù)標(biāo)記為特殊的不常見的數(shù)值;在空閑區(qū)中填充的保護(hù)標(biāo) 記為特殊的不常見的數(shù)值;在空閑區(qū)中填充保護(hù)標(biāo)記的預(yù)定區(qū)域的長度, 根據(jù)實(shí)際需要和策略確定。
本發(fā)明所述的方法,其進(jìn)一步包括
(4) 根據(jù)所述提示內(nèi)存訪問越界的異常信息中包括的申請代碼地址 信息,在程序代碼中進(jìn)行定位,確定所述內(nèi)存塊是在何處申請的,并進(jìn)而 確定所述內(nèi)存塊使用過程中存在的寫入越界情況。
進(jìn)一步地,其步驟(2)所述調(diào)用申請內(nèi)存接口的代碼地址,通過一 個(gè)接口函數(shù)獲得,該接口函數(shù)當(dāng)在某個(gè)函數(shù)FuncA中調(diào)用時(shí),其返回值 為調(diào)用F皿cA的代碼的地址;其所述接口函數(shù)根據(jù)堆棧中函數(shù)調(diào)用鏈,
向后回溯,取得調(diào)用FuncA函數(shù)時(shí)的返回地址,并將該返回地址作為 FuncA函數(shù)的調(diào)用代碼地址。
本發(fā)明所迷方法的出發(fā)點(diǎn),不是實(shí)時(shí)檢測內(nèi)存訪問越界情況,而是在 應(yīng)用程序釋放內(nèi)存時(shí)檢測該內(nèi)存塊的使用過程中是否存在內(nèi)存寫入越界 情況,完全不會影響現(xiàn)有內(nèi)存管理系統(tǒng)中應(yīng)用程序?qū)?nèi)存的使用。本發(fā)明 所述方法不僅檢查內(nèi)存塊尾部保護(hù)字,還檢查空閑區(qū),進(jìn)行了非常完全的 檢查;其次,本發(fā)明所述方法提示內(nèi)存訪問越界的異常信息時(shí),包括了申 請代碼地址信息,根據(jù)此信息在程序代碼中可以進(jìn)行定位,確定該內(nèi)存塊 是在何處申請的,進(jìn)而分析確定內(nèi)存塊使用過程中存在的寫入越界情況, 極大地方便了軟件開發(fā)人員分析出代碼中的問題。本發(fā)明所述的方法對現(xiàn) 有內(nèi)存管理方法的改動很小,能很容易應(yīng)用到現(xiàn)有的內(nèi)存管理系統(tǒng)中,具 有很強(qiáng)的實(shí)用性。
圖1是本發(fā)明實(shí)施例所述的現(xiàn)有內(nèi)存管理方法維護(hù)的內(nèi)存塊信息的 示意圖2是本發(fā)明實(shí)施例所述的內(nèi)存塊增加前端和尾端的保護(hù)信息后的 示意圖。
具體實(shí)施例方式
下面結(jié)合附圖,對本發(fā)明實(shí)施例所述的技術(shù)方案作進(jìn)一步的詳細(xì)描述。
如圖l所示,現(xiàn)有的內(nèi)存管理系統(tǒng)中, 一般在內(nèi)存塊前端定義有前端 信息,用于管理和維護(hù)內(nèi)存塊,而在內(nèi)存塊后端不定義或很少定義尾端信 息,為實(shí)施例描述簡單起見,后面描述中假設(shè)沒有定義尾端信息,盡管如 此,本發(fā)明的方法同樣適用于定義有尾端信息的內(nèi)存管理方法。
如圖2所示,本發(fā)明所述方法在現(xiàn)有前端信息的結(jié)構(gòu)中增加申請代碼 地址信息103。 一般情況下,在嵌入式實(shí)時(shí)系統(tǒng)中,應(yīng)用程序只有一個(gè)代
碼段,因此只需記錄偏移地址。如果應(yīng)用程序包含多個(gè)代碼段,則還需要 在申請代碼地址信息中增加記錄代碼的段地址。為實(shí)施例描述簡單起見,
后面描述中假設(shè)只有一個(gè)代碼段。新的前端信息結(jié)構(gòu)的c語言定義示例
為
typedef struct tagHead
....../*現(xiàn)有的頭部信息成員*/
unsigned long GetEIP; } THea山
GetEIP的類型可根據(jù)CPU類型來確定,如上所述示例是在32位CPU 系統(tǒng)中的定義。
本發(fā)明所述的方法在內(nèi)存塊尾端增加尾端保護(hù)信息,包括保護(hù)字104 和空閑區(qū)長度105。結(jié)構(gòu)定義示例為
typedef struct tagTail
unsigned long TailTag; unsigned short UnusedSize; } TTail;
根據(jù)本發(fā)明所述增加的前端和尾端保護(hù)信息,創(chuàng)建內(nèi)存池時(shí),在現(xiàn)有 內(nèi)存管理方法&出上需要作一定改動,具體方法如下
(1 )初始化一個(gè)可用空間大小為Size的內(nèi)存塊時(shí),實(shí)際需要分配的 內(nèi)存空間為THead大小、TTail大小和Size之和。
(2 )將THead中GetEIP設(shè)定為0。
(3 )將TTail中TailTag設(shè)定為MEM—TAILJTAG (尾端保護(hù)標(biāo)記), 將TTail中UnusedSize設(shè)定為0。 MEM一TAILJTAG為一較特殊的不常見 的數(shù)值,如OxFCFCFCFC等。
根據(jù)本發(fā)明所述的方法,申請內(nèi)存接口需要在為應(yīng)用程序分配的內(nèi)存
塊前端和尾端設(shè)定保護(hù)信息,步驟如下
(1) 假設(shè)應(yīng)用程序所要申請的內(nèi)存大小為UsedSize,實(shí)際為其分配 的內(nèi)存塊大小為Size ( Size>=UsedSize)。
(2) 調(diào)用獲取當(dāng)前函數(shù)調(diào)用代碼地址的接口獲取調(diào)用該申請內(nèi)存接 口的代碼地址(申請代碼地址103 ),將THead中的GetEIP設(shè)定為申請 代碼地址信息。關(guān)于獲取當(dāng)前函數(shù)調(diào)用代碼地址的接口描述詳見后文描述。
(3 )將TTail中TailTag設(shè)定為MEM—TAILJTAG, U加sedSize設(shè)定 為Size-UsedSize。
(4)才艮據(jù)內(nèi)存塊頭部信息地址和所申請大小UsedSize,計(jì)算出空閑 區(qū)102起始地址。根據(jù)UnsedSize以及實(shí)際情況需要,確定空閑區(qū)102中 的保護(hù)長度ProtectSize,比如,Debug版本中ProtectSize等于UnusedSize, 而Release版本中為提高效率,限制ProtectSize不能超過預(yù)定的最大值。 從空閑區(qū)102起始地址開始,將ProtectSize大小的內(nèi)存區(qū)域中的每個(gè)字節(jié) 設(shè)定為MEM—UNUSED—TAG (空閑保護(hù)標(biāo)記)。MEM—UNUSED—TAG 為一較特殊的不常見的數(shù)值,如OxFC等。
根據(jù)本發(fā)明所述的方法,釋放內(nèi)存接口需要根據(jù)尾端信息中保護(hù)字 104以及空閑區(qū)105來檢測是否存在內(nèi)存寫入越界情況,步驟如下
(1 )根據(jù)輸入?yún)?shù)中的內(nèi)存指針可計(jì)算出內(nèi)存塊頭部信息101地址, 一般根據(jù)頭部信息101可取得內(nèi)存塊可用大小Size,再根據(jù)頭部信息101 地址和內(nèi)存可用大小Size計(jì)算出尾端信息地址。
(2)才艮據(jù)尾端信息地址讀出尾端信息中保護(hù)字104,檢查保護(hù)字104 是否是預(yù)先設(shè)定的值(MEM—TAIL—TAG ),如果是,繼續(xù)步驟(3),否 則提示內(nèi)存訪問越界的異常信息,其中包括從前端信息中獲取的申請代碼 地址GetEIP。
(3 )根據(jù)尾端信息TTail中的UnusedSize,計(jì)算出空閑區(qū)102起始 地址,并才艮據(jù)申請內(nèi)存接口中相同策略確定空閑區(qū)保護(hù)長度ProtectSize。
從空閑區(qū)102起始地址開始,逐個(gè)檢查ProtectSize大小的區(qū)域中每個(gè)字節(jié) 的值是否是預(yù)先設(shè)定的值(MEM—UNUSED_TAG)。如果發(fā)現(xiàn)某個(gè)字節(jié) 的值不是MEM—UNUSED—TAG,則提示內(nèi)存訪問越界的異常信息,其中 包括從前端信息中獲取的申請代碼地址GetEIP。
根據(jù)本發(fā)明所述的方法,需要提供一個(gè)獲取當(dāng)前函數(shù)調(diào)用代碼地址的 接口,其功能和實(shí)現(xiàn)描述如下
設(shè)該接口函數(shù)名為GetEIPFunc,其功能是當(dāng)GetEIPFunc在某個(gè)函數(shù) FuncA中調(diào)用時(shí),其返回值為調(diào)用FuncA的代碼的地址。
其實(shí)現(xiàn)方法是^L據(jù)堆棧中函數(shù)調(diào)用鏈,向后回溯,取得調(diào)用FuncA 函數(shù)時(shí)的返回地址,我們將此返回地址看作為FuncA函數(shù)的調(diào)用代碼地 址。具體實(shí)現(xiàn)根據(jù)CPU類型和編譯器的不同而有所不同。
上述具體實(shí)施方式
以較佳實(shí)施例對本發(fā)明進(jìn)行了 ^L明,不應(yīng)譯皮視為對 本發(fā)明范圍的限制。同樣,根據(jù)本發(fā)明的技術(shù)方案及其較佳實(shí)施例的描述, 可以做出各種可能的等同改變或替換,而所有這些改變或替換都應(yīng)屬于本 發(fā)明權(quán)利要求的保護(hù)范圍。
權(quán)利要求
1、一種檢測內(nèi)存訪問越界的方法,在應(yīng)用程序使用從內(nèi)存池中申請的內(nèi)存塊的過程中,檢測是否存在內(nèi)存寫入越界的情況,其特征在于,包括如下步驟(1)創(chuàng)建內(nèi)存池時(shí),如果初始化一個(gè)可用空間大小為Size的內(nèi)存塊,則需要為其分配的全部內(nèi)存空間為可用空間大小Size加上需要為該內(nèi)存塊添加的前端信息和尾端信息所占空間大小之和,其中,所述尾端信息包括保護(hù)字信息、空閑區(qū)長度信息;(2)應(yīng)用程序申請內(nèi)存時(shí),如果為其找到一個(gè)合適的內(nèi)存塊,則將所述內(nèi)存塊的尾端信息中的保護(hù)字設(shè)定為保護(hù)標(biāo)記,將空閑區(qū)長度設(shè)定為內(nèi)存塊大小Size減去用戶申請大小的值,如果空閑區(qū)長度不為零,則在從所述空閑區(qū)起始地址開始,在預(yù)設(shè)區(qū)域填充保護(hù)標(biāo)記;(3)應(yīng)用程序釋放內(nèi)存時(shí),檢測尾端信息中的保護(hù)字是否為設(shè)定的保護(hù)標(biāo)記,如果不是,則提示內(nèi)存訪問越界的異常信息;如果保護(hù)字是設(shè)定的保護(hù)標(biāo)記,則檢測空閑區(qū)中已填充保護(hù)標(biāo)記的區(qū)域,當(dāng)發(fā)現(xiàn)某處不是設(shè)定的保護(hù)標(biāo)記時(shí),提示內(nèi)存訪問越界的異常信息。
2、 如權(quán)利要求1所述的方法,其特征在于,步驟(1)中進(jìn)一步包括 所述前端信息包括頭部信息、申請代碼地址信息,所述內(nèi)存塊可用空間在 實(shí)際使用時(shí)分為用戶數(shù)據(jù)區(qū)與空閑區(qū);步驟(2)中進(jìn)一步包括所述內(nèi)存塊的前端信息中填寫頭部信息, 并將申請代碼地址設(shè)定為所獲得的調(diào)用申請內(nèi)存接口的代碼地址;步驟(3)中進(jìn)一步包括所述提示內(nèi)存訪問越界的異常信息中包括 申請代碼地址信息。
3、 如權(quán)利要求2所述的方法,其特征在于,所述步驟(2)中,如果 應(yīng)用程序只有一個(gè)代碼段,則在申請代碼地址信息中只需記錄偏移地址。
4、 如權(quán)利要求2所述的方法,其特征在于,所述步驟(2)中,如果 應(yīng)用程序包含多個(gè)代碼段,則在申請代碼地址信息中進(jìn)一步記錄代碼的段 地址。
5、 如權(quán)利要求l所述的方法,其特征在于,所述步驟(2)中,尾端 信息中的保護(hù)字設(shè)定的保護(hù)標(biāo)記為特殊的不常見的數(shù)值。
6、 如權(quán)利要求l所述的方法,其特征在于,所述步驟(2)中,在空 閑區(qū)中填充的保護(hù)標(biāo)記為特殊的不常見的數(shù)值。
7、 如權(quán)利要求l所述的方法,其特征在于,所述步驟(2)中,在空 閑區(qū)中填充保護(hù)標(biāo)記的預(yù)定區(qū)域的長度,根據(jù)實(shí)際需要和策略確定。
8、 如權(quán)利要求2所述的方法,其特征在于,步驟(2)所述調(diào)用申請 內(nèi)存接口的代碼地址,通過一個(gè)接口函數(shù)獲得,該接口函數(shù)當(dāng)在某個(gè)函數(shù) F皿cA中調(diào)用時(shí),其返回值為調(diào)用FuncA的代碼的地址。
全文摘要
本發(fā)明公開了一種檢測內(nèi)存訪問越界的方法,在應(yīng)用程序使用從內(nèi)存池中申請的內(nèi)存塊的過程中,檢測是否存在內(nèi)存寫入越界的情況,包括主要步驟在應(yīng)用程序所申請內(nèi)存塊的前端增加申請?jiān)搩?nèi)存塊的調(diào)用代碼地址信息,尾端增加保護(hù)字和空閑區(qū)長度信息,同時(shí)在空閑區(qū)填充保護(hù)標(biāo)記,當(dāng)應(yīng)用程序釋放內(nèi)存時(shí),檢測是否存在內(nèi)存寫入越界,并提示相關(guān)的異常信息,其中包括申請代碼地址信息。本發(fā)明所述的方法對現(xiàn)有內(nèi)存管理方法的改動很小,能很容易應(yīng)用到現(xiàn)有的內(nèi)存管理系統(tǒng)中,具有很強(qiáng)的實(shí)用性。
文檔編號G06F12/02GK101110042SQ20061010326
公開日2008年1月23日 申請日期2006年7月20日 優(yōu)先權(quán)日2006年7月20日
發(fā)明者劉晨吉, 王國兵, 超 羅 申請人:中興通訊股份有限公司