国产精品1024永久观看,大尺度欧美暖暖视频在线观看,亚洲宅男精品一区在线观看,欧美日韩一区二区三区视频,2021中文字幕在线观看

  • <option id="fbvk0"></option>
    1. <rt id="fbvk0"><tr id="fbvk0"></tr></rt>
      <center id="fbvk0"><optgroup id="fbvk0"></optgroup></center>
      <center id="fbvk0"></center>

      <li id="fbvk0"><abbr id="fbvk0"><dl id="fbvk0"></dl></abbr></li>

      數(shù)組越界錯(cuò)誤的自動(dòng)檢測(cè)和校正方法

      文檔序號(hào):6536010閱讀:424來(lái)源:國(guó)知局
      數(shù)組越界錯(cuò)誤的自動(dòng)檢測(cè)和校正方法
      【專利摘要】本發(fā)明提供一種數(shù)組越界錯(cuò)誤的自動(dòng)檢測(cè)和校正方法,包括:選擇待變換的源代碼;利用編譯器生成源代碼的符號(hào)表和抽象語(yǔ)法樹;遍歷抽象語(yǔ)法樹,構(gòu)造指針依賴圖,并進(jìn)行源代碼變換計(jì)算;在源代碼中將需替換的部分源代碼進(jìn)行替換;將按照數(shù)組越界檢測(cè)策略和校正策略生成的函數(shù)定義寫入變換后源代碼的開頭部分;將變換后的源代碼用原編譯器進(jìn)行編譯;把生成的可執(zhí)行文件部署到目標(biāo)系統(tǒng)并運(yùn)行,自動(dòng)檢測(cè)和校正數(shù)組越界錯(cuò)誤,并準(zhǔn)確報(bào)告錯(cuò)誤對(duì)應(yīng)的源代碼位置。本發(fā)明提供的數(shù)組越界錯(cuò)誤的自動(dòng)檢測(cè)和校正方法具有更準(zhǔn)確的錯(cuò)誤定位功能,更好的運(yùn)行時(shí)效率和性能,更自動(dòng)化的運(yùn)行時(shí)錯(cuò)誤校正功能。
      【專利說明】數(shù)組越界錯(cuò)誤的自動(dòng)檢測(cè)和校正方法
      【技術(shù)領(lǐng)域】
      [0001]本發(fā)明涉及計(jì)算機(jī)軟件測(cè)試和校正【技術(shù)領(lǐng)域】,特別涉及一種數(shù)組越界錯(cuò)誤的自動(dòng)檢測(cè)和校正方法。
      【背景技術(shù)】
      [0002]緩沖區(qū)溢出是一種非常危險(xiǎn)的軟件漏洞,并廣泛存在于各種應(yīng)用軟件中。緩沖區(qū)溢出漏洞可能導(dǎo)致軟件行為異常、內(nèi)存訪問錯(cuò)誤或系統(tǒng)崩潰,也可被黑客用來(lái)攻擊有價(jià)值的軟件系統(tǒng)。目前,緩沖區(qū)溢出問題已經(jīng)成為造成軟件漏洞的主要原因。例如,根據(jù)US-CERT漏洞數(shù)據(jù)庫(kù)統(tǒng)計(jì)資料可知,在20個(gè)最嚴(yán)重的漏洞中,就有11個(gè)是由緩沖區(qū)溢出引起。尤其對(duì)于那些用于控制安全關(guān)鍵工業(yè)系統(tǒng)的嵌入式控制軟件(例如,飛行控制軟件、高速列車控制軟件、核電站控制軟件等)和安全關(guān)鍵應(yīng)用軟件系統(tǒng)(例如,銀行交易軟件、網(wǎng)上交易軟件等),當(dāng)因緩沖區(qū)溢出漏洞引起軟件失效、系統(tǒng)故障或黑客攻擊,損失將非常慘重。因此,有效的緩沖區(qū)溢出檢測(cè)和校正技術(shù)是軟件研發(fā)和維護(hù)中的重要問題。
      [0003]軟件中緩沖區(qū)的內(nèi)存分配包括兩種方式:靜態(tài)內(nèi)存分配和動(dòng)態(tài)內(nèi)存分配。靜態(tài)內(nèi)存分配主要指源代碼中變量和數(shù)組的定義,而動(dòng)態(tài)內(nèi)存分配主要指使用malloc等內(nèi)存管理函數(shù)為軟件分配的堆空間。通常,不帶操作系統(tǒng)或內(nèi)存管理模塊的嵌入式工業(yè)控制系統(tǒng)不支持動(dòng)態(tài)內(nèi)存分配。因此,在這樣的系統(tǒng)中,數(shù)組越界訪問成為了緩沖區(qū)溢出的主要表現(xiàn)形式。也就是說,檢測(cè)和校正軟件中的數(shù)組越界錯(cuò)誤是避免緩沖區(qū)溢出的主要方式。
      [0004]目前,現(xiàn)有的檢測(cè)數(shù)組越界錯(cuò)誤的方法分為兩種類型:靜態(tài)方法和動(dòng)態(tài)方法。
      [0005]靜態(tài)方法是指通過分析軟件設(shè)計(jì)模型或者源代碼來(lái)檢驗(yàn)錯(cuò)誤的方法,而不需要實(shí)際運(yùn)行該軟件。除人工代碼走查之外,靜態(tài)方法的一個(gè)主流技術(shù)是模型檢驗(yàn)技術(shù),例如SPIN模型檢驗(yàn)器等。模型檢驗(yàn)工具一般通過抽象建模,運(yùn)行驗(yàn)證,生成和分析反例等步驟來(lái)檢驗(yàn)設(shè)計(jì)模型的正確性。例如,業(yè)內(nèi)曾經(jīng)使用SPIN模型檢驗(yàn)器對(duì)某型國(guó)產(chǎn)飛機(jī)的飛行控制系統(tǒng)的緩沖區(qū)控制模塊的設(shè)計(jì)模型進(jìn)行了驗(yàn)證,準(zhǔn)確地找出了由模塊間復(fù)雜交互行為引起的數(shù)組越界錯(cuò)誤。模型檢驗(yàn)技術(shù)的優(yōu)點(diǎn)在于,可以對(duì)軟件所有可能的行為進(jìn)行窮舉搜索,確保結(jié)果的完備性。然而,該技術(shù)的不足之處在于:1、由于模型檢驗(yàn)技術(shù)本身的計(jì)算復(fù)雜性是PSPACE完全的,因此它與生俱來(lái)的狀態(tài)爆炸問題使得該技術(shù)很難直接被應(yīng)用于較大規(guī)模軟件的驗(yàn)證,例如超過10000行代碼的軟件;2、由于模型檢驗(yàn)技術(shù)通常是對(duì)軟件系統(tǒng)抽象出來(lái)的設(shè)計(jì)模型進(jìn)行驗(yàn)證,而不是全部源代碼,所以無(wú)法確保該軟件的實(shí)際實(shí)現(xiàn)是正確的,即無(wú)法確保源代碼的正確性。
      [0006]動(dòng)態(tài)方法是指通過運(yùn)行軟件,并在軟件運(yùn)行過程中檢測(cè)錯(cuò)誤的方法。動(dòng)態(tài)方法的一個(gè)主流技術(shù)是軟件測(cè)試技術(shù)。軟件測(cè)試工具一般通過編譯源代碼、運(yùn)行待測(cè)試軟件等步驟,在軟件運(yùn)行過程中根據(jù)設(shè)計(jì)的測(cè)試用例注入測(cè)試數(shù)據(jù),通過對(duì)軟件的輸出進(jìn)行分析(例如,與測(cè)試用例的預(yù)計(jì)輸出進(jìn)行對(duì)比),來(lái)觀察軟件運(yùn)行是否正確,檢測(cè)軟件是否存在錯(cuò)誤。軟件測(cè)試技術(shù)的優(yōu)點(diǎn)在于,有一定的自動(dòng)化功能,可以進(jìn)行測(cè)試用例管理、批量測(cè)試和回歸測(cè)試。然而,該技術(shù)的不足之處在于:1、由于不直接面對(duì)源代碼,無(wú)法準(zhǔn)確定位導(dǎo)致錯(cuò)誤發(fā)生的源代碼位置;2、由于錯(cuò)誤定位不準(zhǔn)確,為軟件的開發(fā)調(diào)試和校正造成了障礙。
      [0007]另一種有效的動(dòng)態(tài)方法是將軟件在一個(gè)虛擬機(jī)上運(yùn)行,該虛擬機(jī)可以模擬內(nèi)存管理模塊,從而檢測(cè)軟件中的數(shù)組越界錯(cuò)誤。例如JAVA虛擬機(jī)就是一個(gè)典型的代表。虛擬機(jī)技術(shù)的優(yōu)點(diǎn)在于,由于整個(gè)軟件都處于被監(jiān)控的狀態(tài),因此檢測(cè)結(jié)果非常準(zhǔn)確。然而,該技術(shù)的不足之處在于:1、由于虛擬機(jī)對(duì)軟件的解釋執(zhí)行,使得軟件運(yùn)行負(fù)載過大,以至于軟件效率和性能降低非常明顯;2、對(duì)于嵌入式安全關(guān)鍵工業(yè)控制系統(tǒng),由于高實(shí)時(shí)性和內(nèi)存資源受限的要求,這樣的效率和性能降低往往不能被接受,因此這種方法并不實(shí)用。
      [0008]在檢測(cè)到錯(cuò)誤的存在后,就需要對(duì)錯(cuò)誤進(jìn)行校正,比如修改源代碼。對(duì)于校正數(shù)組越界訪問錯(cuò)誤,常用的方法是人工調(diào)試和校正。也就是說,在軟件測(cè)試階段,根據(jù)軟件測(cè)試工具的測(cè)試報(bào)告,由程序員使用代碼調(diào)試工具,人工分析源代碼的執(zhí)行過程來(lái)定位錯(cuò)誤。這一方法的優(yōu)點(diǎn)是容易操作,不需要使用額外的工具。然而,該技術(shù)的不足之處在于:1、當(dāng)源代碼規(guī)模較大或者功能較為復(fù)雜,程序員不一定能準(zhǔn)確定位錯(cuò)誤在源代碼中的位置,從而無(wú)法正確地修改源代碼;2、當(dāng)軟件已經(jīng)被部署到目標(biāo)平臺(tái)上,在實(shí)際運(yùn)行過程中出現(xiàn)的數(shù)組越界訪問錯(cuò)誤無(wú)法通過這種方法進(jìn)行校正,因此可能會(huì)引起軟件失效、系統(tǒng)故障或黑客攻擊。
      [0009]因此,有必要提供一種新的數(shù)組越界錯(cuò)誤的自動(dòng)檢測(cè)和校正方法,以實(shí)現(xiàn)更準(zhǔn)確的錯(cuò)誤定位功能,更好的運(yùn)行時(shí)效率和性能,以及更自動(dòng)化的運(yùn)行時(shí)錯(cuò)誤校正功能,從而克服現(xiàn)有的檢測(cè)數(shù)組越界錯(cuò)誤的方法中存在的技術(shù)問題。

      【發(fā)明內(nèi)容】

      [0010]為了克服上述已有技術(shù)存在的不足,本發(fā)明的目的旨在提供一種新的檢測(cè)和校正數(shù)組越界錯(cuò)誤的方法,通過使用源代碼變換技術(shù),將源代碼變換為帶有自動(dòng)檢測(cè)和校正功能的源代碼,使得可以在軟件運(yùn)行過程中自動(dòng)檢測(cè)和校正軟件中數(shù)組越界錯(cuò)誤,以實(shí)現(xiàn)更準(zhǔn)確的錯(cuò)誤定位功能,更好的運(yùn)行時(shí)效率和性能,以及更自動(dòng)化的運(yùn)行時(shí)錯(cuò)誤校正功能,從而克服現(xiàn)有的檢測(cè)數(shù)組越界錯(cuò)誤的方法中存在的技術(shù)問題。
      [0011]本發(fā)明提供一種數(shù)組越界錯(cuò)誤的自動(dòng)檢測(cè)和校正方法,其特征在于,包括:步驟
      1、選擇待變換的源代碼項(xiàng)目目錄,或者單個(gè)源代碼文件;步驟2、針對(duì)待變換的源代碼,利用編譯器生成源代碼的符號(hào)表和抽象語(yǔ)法樹;步驟3、遍歷抽象語(yǔ)法樹中的所有結(jié)點(diǎn),構(gòu)造指針依賴圖,并進(jìn)行源代碼變換計(jì)算;步驟4、根據(jù)步驟3的計(jì)算結(jié)果,在源代碼中將需替換的部分源代碼進(jìn)行替換,生成變換后的源代碼,并保存到新項(xiàng)目目錄或新文件;步驟5、定義數(shù)組越界檢測(cè)策略和校正策略,并將這些策略轉(zhuǎn)化為函數(shù)定義,將按照策略生成的函數(shù)定義寫入變換后源代碼的開頭部分;步驟6、將變換后的項(xiàng)目目錄或文件用原編譯器進(jìn)行編譯,生成目標(biāo)系統(tǒng)上的可執(zhí)行文件;步驟7、把生成的可執(zhí)行文件部署到目標(biāo)系統(tǒng)并運(yùn)行,當(dāng)可執(zhí)行文件運(yùn)行到那些替換或插入的代碼段時(shí),將自動(dòng)檢測(cè)和校正數(shù)組越界錯(cuò)誤,并準(zhǔn)確報(bào)告錯(cuò)誤對(duì)應(yīng)的源代碼位置。
      [0012]進(jìn)一步地,所述遍歷抽象語(yǔ)法樹中的所有結(jié)點(diǎn),構(gòu)造指針依賴圖,并進(jìn)行源代碼變換計(jì)算,包括:指針依賴圖是一個(gè)有向圖二元組(V,E),其中:V是源代碼中的指針集合并構(gòu)成指針依賴圖中的結(jié)點(diǎn)集合,E是源代碼中的指針依賴關(guān)系集合并構(gòu)成指針依賴圖中的有向邊集合;在遍歷抽象語(yǔ)法樹的過程中,根據(jù)當(dāng)前遍歷到的結(jié)點(diǎn)s的類型進(jìn)行如下操作之一:向指針依賴圖中加入指針依賴關(guān)系,將數(shù)組下標(biāo)訪問表達(dá)式和指針訪問表達(dá)式替換為函數(shù)調(diào)用,將函數(shù)聲明、函數(shù)定義、函數(shù)調(diào)用表達(dá)式替換為新的表達(dá)式。
      [0013]進(jìn)一步地,所述在遍歷抽象語(yǔ)法樹的過程中,根據(jù)當(dāng)前遍歷到的結(jié)點(diǎn)s的類型進(jìn)行如下操作之一:向指針依賴圖中加入指針依賴關(guān)系,將數(shù)組下標(biāo)訪問表達(dá)式和指針訪問表達(dá)式替換為函數(shù)調(diào)用,將函數(shù)聲明、函數(shù)定義、函數(shù)調(diào)用表達(dá)式替換為新的表達(dá)式,包括:在遍歷抽象語(yǔ)法樹的過程中,對(duì)于當(dāng)前遍歷到的結(jié)點(diǎn)s,得到其所在的源文件名filename和代碼行號(hào)loc,并根據(jù)結(jié)點(diǎn)s的類型分別進(jìn)行如下操作:
      [0014]操作1、如果結(jié)點(diǎn)s是一個(gè)帶初始值的指針聲明type*p=expr,其中p為指針名,expr為表達(dá)式,且expr中包含一個(gè)支配指針q,則將(P, q)作為一條邊加入指針依賴圖;
      [0015]操作2、如果結(jié)點(diǎn)s是一個(gè)指針賦值表達(dá)式p=expr,其中p為指針名,expr為表達(dá)式,且expr中包含一個(gè)支配指針q,則將(P,q)作為一條邊加入指針依賴圖;
      [0016]操作3、如果結(jié)點(diǎn)s是一個(gè)數(shù)組下標(biāo)表達(dá)式P [expr],其中p為指針名或數(shù)組名,expr為表達(dá)式,則根據(jù)P的類型分別進(jìn)行如下操作:
      [0017]操作31、如果P是符號(hào)表中已定義的一個(gè)數(shù)組,則從符號(hào)表中獲取該數(shù)組的類型type和長(zhǎng)度len,然后將該表達(dá)式替換為如下函數(shù)調(diào)用:
      [0018]* ((type*)(—MNT_CHECK_AAV(p+expr, p, p+len, filename, loc)))
      [0019]其中,函數(shù)參數(shù)p+expr表示數(shù)組下標(biāo)表達(dá)式訪問的內(nèi)存地址,函數(shù)參數(shù)P表示數(shù)組的起始地址,函數(shù)參數(shù)P+len表示數(shù)組的結(jié)束地址,函數(shù)參數(shù)filename表示源文件名,函數(shù)參數(shù)1c表示代碼行號(hào);
      [0020]操作32、如果P 是所在函數(shù)聲明的第η個(gè)形式參數(shù),則從符號(hào)表中獲取該指針的類型type,然后將該表達(dá)式替換為如下函數(shù)調(diào)用:
      [0021 ] * ((type*) (__MNT_CHK_AAV(p+expr, __MNT_CHK_AAV_B_n, __MNT_CHK_AAV_E_n, filename, loc)))
      [0022]其中,函數(shù)參數(shù)p+expr表示數(shù)組下標(biāo)表達(dá)式訪問的內(nèi)存地址,函數(shù)參數(shù)—MNT_CHK_AAV_B_n表示第η個(gè)形式參數(shù)的起始地址,函數(shù)參數(shù)—MNT_CHK_AAV_E_n表示第η個(gè)形式參數(shù)的結(jié)束地址,函數(shù)參數(shù)filename表示源文件名,函數(shù)參數(shù)1c表示代碼行號(hào);
      [0023]操作33、如果P是不滿足以上操作31、操作32中的兩種情況的指針,則從指針依賴圖中獲取其最終依賴指針q,如果q不存在,則認(rèn)為源代碼中存在指針使用前未賦初值的錯(cuò)誤,并報(bào)錯(cuò),如果q存在,則根據(jù)q的類型分別進(jìn)行如下操作:
      [0024]操作331、如果q是符號(hào)表中已定義的一個(gè)數(shù)組,則從符號(hào)表中獲取指針P的類型type和數(shù)組q的長(zhǎng)度len,然后將該表達(dá)式替換為如下函數(shù)調(diào)用:
      [0025]*((type*)(—MNT_CHECK_AAV(p+expr, q, q+len, filename, loc)))
      [0026]其中,函數(shù)參數(shù)p+expr表示數(shù)組下標(biāo)表達(dá)式訪問的內(nèi)存地址,函數(shù)參數(shù)q表示數(shù)組的起始地址,函數(shù)參數(shù)q+len表示數(shù)組的結(jié)束地址,函數(shù)參數(shù)filename表示源文件名,函數(shù)參數(shù)1c表示代碼行號(hào);
      [0027]操作332、如果q是所在函數(shù)聲明的第η個(gè)形式參數(shù),則從符號(hào)表中獲取指針P的類型type,然后將該表 達(dá)式替換為如下函數(shù)調(diào)用:
      [0028]* ((type*) (__MNT_CHK_AAV(p+expr, __MNT_CHK_AAV_B_n, __MNT_CHK_AAV_E_n, filename, loc)))[0029]其中,函數(shù)參數(shù)p+expr表示數(shù)組下標(biāo)表達(dá)式訪問的內(nèi)存地址,函數(shù)參數(shù)—MNT_CHK_AAV_B_n表示第η個(gè)形式參數(shù)的起始地址,函數(shù)參數(shù)—MNT_CHK_AAV_E_n表示第η個(gè)形式參數(shù)的結(jié)束地址,函數(shù)參數(shù)filename表示源文件名,函數(shù)參數(shù)1c表示代碼行號(hào);
      [0030]操作333、如果q是不滿足以上操作331、操作332中的兩種情況的指針,則認(rèn)為源代碼中存在指針使用前未賦初值的錯(cuò)誤,并報(bào)錯(cuò);
      [0031]操作4、如果結(jié)點(diǎn)s是一個(gè)指針訪問表達(dá)式*expr,其中expr為表達(dá)式,且expr中包含一個(gè)支配指針P,則根據(jù)P的類型分別進(jìn)行如下操作:
      [0032]操作41、如果P是符號(hào)表中已定義的一個(gè)數(shù)組,則從符號(hào)表中獲取該數(shù)組的類型type和長(zhǎng)度len,然后將該表達(dá)式替換為如下函數(shù)調(diào)用:
      [0033]* ((type*)(—MNT_CHECK_AAV(expr, p, p+len, filename, loc)))
      [0034]其中,函數(shù)參數(shù)expr表示指針訪問表達(dá)式訪問的內(nèi)存地址,函數(shù)參數(shù)P表示數(shù)組的起始地址,函數(shù)參數(shù)P+len表示數(shù)組的結(jié)束地址,函數(shù)參數(shù)filename表示源文件名,函數(shù)參數(shù)1c表示代碼行號(hào);
      [0035]操作42、如果P是所在函數(shù)聲明的第η個(gè)形式參數(shù),則從符號(hào)表中獲取該指針的類型type,然后將該表達(dá)式替換為如下函數(shù)調(diào)用:
      [0036]* ((type*) (__MNT_CHK_AAV(expr, __MNT_CHK_AAV_B_n, __MNT_CHK_AAV_E_n, filename, loc)))
      [0037]其中,函數(shù)參數(shù)e`xpr表示指針訪問表達(dá)式訪問的內(nèi)存地址,函數(shù)參數(shù)—MNT_CHK_AAV_B_n表示第η個(gè)形式參數(shù)的起始地址,函數(shù)參數(shù)—MNT_CHK_AAV_E_n表示第η個(gè)形式參數(shù)的結(jié)束地址,函數(shù)參數(shù)filename表示源文件名,函數(shù)參數(shù)1c表示代碼行號(hào);
      [0038]操作43、如果P是不滿足以上操作41、操作42中的兩種情況的指針,則從指針依賴圖中獲取其最終依賴指針q,如果q不存在,則認(rèn)為源代碼中存在指針使用前未賦初值的錯(cuò)誤,并報(bào)錯(cuò),如果q存在,則根據(jù)q的類型分別進(jìn)行如下操作:
      [0039]操作431、如果q是符號(hào)表中已定義的一個(gè)數(shù)組,則從符號(hào)表中獲取指針P的類型type和數(shù)組q的長(zhǎng)度len,然后將該表達(dá)式替換為如下函數(shù)調(diào)用:
      [0040]*((type*)(—MNT_CHECK_AAV(expr, q, q+len, filename, loc)))
      [0041]其中,函數(shù)參數(shù)expr表示指針訪問表達(dá)式訪問的內(nèi)存地址,函數(shù)參數(shù)q表示數(shù)組的起始地址,函數(shù)參數(shù)q+len表示數(shù)組的結(jié)束地址,函數(shù)參數(shù)filename表示源文件名,函數(shù)參數(shù)1c表示代碼行號(hào);
      [0042]操作432、如果q是所在函數(shù)聲明的第η個(gè)形式參數(shù),則從符號(hào)表中獲取指針P的類型type,然后將該表達(dá)式替換為如下函數(shù)調(diào)用:
      [0043]* ((type*) (__MNT_CHK_AAV(expr, __MNT_CHK_AAV_B_n, __MNT_CHK_AAV_E_n, filename, loc)))
      [0044]其中,函數(shù)參數(shù)expr表示指針訪問表達(dá)式訪問的內(nèi)存地址,函數(shù)參數(shù)—MNT_CHK_AAV_B_n表示第η個(gè)形式參數(shù)的起始地址,函數(shù)參數(shù)—MNT_CHK_AAV_E_n表示第η個(gè)形式參數(shù)的結(jié)束地址,函數(shù)參數(shù)filename表示源文件名,函數(shù)參數(shù)1c表示代碼行號(hào);
      [0045]操作433、如果q是不滿足以上操作431、操作432中的兩種情況的指針,則認(rèn)為源代碼中存在指針使用前未賦初值的錯(cuò)誤,并報(bào)錯(cuò);
      [0046]操作5、如果結(jié)點(diǎn)s是一個(gè)函數(shù)聲明或函數(shù)定義表達(dá)式type func (…,type_nexpr_n,…),其中:第η個(gè)參數(shù)表達(dá)式expr_n為type_n類型的數(shù)組或指針聲明p,省略號(hào)…表示其它參數(shù)表達(dá)式,則將該函數(shù)聲明或函數(shù)定義替換為如下函數(shù):
      [0047]type func(..., type_n expr_n, void*—MNT_CHK_AAV_B_n, void*—MNT_CHK_AAV_E_n,...)
      [0048]其中,省略號(hào)…表示原來(lái)的所有參數(shù)表達(dá)式,函數(shù)參數(shù)—MNT_CHK_AAV_B_n表示第η個(gè)參數(shù)表達(dá)式的起始地址,函數(shù)參數(shù)—MNT_CHK_AAV_E_n表示第η個(gè)參數(shù)表達(dá)式的結(jié)束地址;
      [0049]操作6、如果結(jié)點(diǎn)s是一個(gè)函數(shù)調(diào)用表達(dá)式func(...,expr_n,…),其中:第η個(gè)參數(shù)表達(dá)式expr_n中包含一個(gè)支配指針p,省略號(hào)…表示其它參數(shù)表達(dá)式,則根據(jù)P的類型分別進(jìn)行如下操作:
      [0050]操作61、如果P是符號(hào)表中已定義的一個(gè)數(shù)組,則從符號(hào)表中獲取該數(shù)組的長(zhǎng)度len,然后將該表達(dá)式替換為如下函數(shù)調(diào)用:func(...,expr_n, p, p+len,…),其中,省略號(hào)…表示原來(lái)的所有參數(shù)表達(dá)式,函數(shù)參數(shù)P表示數(shù)組的起始地址,函數(shù)參數(shù)p+len表示數(shù)組的結(jié)束地址;
      [0051]操作62、如果P是所在函數(shù)聲明的第η個(gè)形式參數(shù),則將該表達(dá)式替換為如下函數(shù)調(diào)用:
      [0052]func (…,expr_n, —MNT_CHK_AAV_B_n, _MNT_CHK_AAV_E_n,…)
      [0053]其中,省略號(hào)…表不原來(lái)的所有參數(shù)表達(dá)式,函數(shù)參數(shù)—MNT_CHK_AAV_B_n表不第η個(gè)形式參數(shù)的起始地址,函數(shù)參數(shù)—MNT_CHK_AAV_E_n表示第η個(gè)形式參數(shù)的結(jié)束地址;
      `[0054]操作63、如果P是不滿足以上操作61、操作62中的兩種情況的指針,則從指針依賴圖中獲取其最終依賴指針q,如果q不存在,則認(rèn)為源代碼中存在指針使用前未賦初值的錯(cuò)誤,并報(bào)錯(cuò),如果q存在,則根據(jù)q的類型分別進(jìn)行如下操作:
      [0055]操作631、如果q是符號(hào)表中已定義的一個(gè)數(shù)組,則從符號(hào)表中獲取數(shù)組q的長(zhǎng)度len,然后將該表達(dá)式替換為如下函數(shù)調(diào)用:func(...,expr_n, q, q+len,…),其中,省略號(hào)…表示原來(lái)的所有參數(shù)表達(dá)式,函數(shù)參數(shù)q表示數(shù)組的起始地址,函數(shù)參數(shù)q+len表示數(shù)組的結(jié)束地址;
      [0056]操作632、如果q是所在函數(shù)聲明的第η個(gè)形式參數(shù),則將該表達(dá)式替換為如下函數(shù)調(diào)用:
      [0057]func (…,expr_n, —MNT_CHK_AAV_B_n, _MNT_CHK_AAV_E_n,…)
      [0058]其中,省略號(hào)…表不原來(lái)的所有參數(shù)表達(dá)式,函數(shù)參數(shù)—MNT_CHK_AAV_B_n表不第η個(gè)形式參數(shù)的起始地址,函數(shù)參數(shù)—MNT_CHK_AAV_E_n表示第η個(gè)形式參數(shù)的結(jié)束地址;
      [0059]操作633、如果q是不滿足以上操作631、操作632中的兩種情況的指針,則認(rèn)為源代碼中存在指針使用前未賦初值的錯(cuò)誤,并報(bào)錯(cuò)。
      [0060]進(jìn)一步地,所述步驟3包括:在指針依賴圖中,從P開始沿有向邊往前遍歷,直到訪問到一個(gè)沒有后繼結(jié)點(diǎn)的指針q,那么q就是P的最終依賴指針。
      [0061]進(jìn)一步地,所述步驟3包括:支配指針是指決定該表達(dá)式指向地址的主要指針變量;該表達(dá)式的其他部分決定相對(duì)于該指針指向地址的偏移量。[0062]進(jìn)一步地,所述檢測(cè)策略包括:判斷要訪問的地址P是否在允許的范圍[begin, end)之間,如果超出該范圍,則報(bào)告數(shù)組越界錯(cuò)誤。
      [0063]進(jìn)一步地,所述校正策略包括:當(dāng)合法的內(nèi)存范圍為[begin,end),大小為η時(shí),
      [0064]如果訪問地址P為下越界,則將P和begin之間的偏移量進(jìn)行模η運(yùn)算,并被end減后作為映射的合法訪問地址;
      [0065]如果訪問地址P為上越界,則將P和end之間的偏移量進(jìn)行模η運(yùn)算,并加上begin作為映射的合法訪問地址;
      [0066]如果訪問地址P在[begin, end)范圍內(nèi),則不作任何計(jì)算;
      [0067]任何的內(nèi)存訪問都能被映射到合法的內(nèi)存范圍[begin, end)內(nèi)。
      [0068]進(jìn)一步地,所述步驟5包括:檢測(cè)策略和校正策略直接通過源代碼的方式說明;或者,使用特別定義的描述語(yǔ)言來(lái)說明,并通過語(yǔ)言自動(dòng)轉(zhuǎn)化工具自動(dòng)翻譯為源代碼。
      [0069]本發(fā)明提供的數(shù)組越界錯(cuò)誤的自動(dòng)檢測(cè)和校正方法通過對(duì)源代碼的抽象語(yǔ)法樹進(jìn)行分析,具有充分的語(yǔ)義信息來(lái)判斷潛在的數(shù)組越界錯(cuò)誤所在的源文件和代碼行,并相應(yīng)地進(jìn)行源代碼變換,使得在錯(cuò)誤檢測(cè)中可以使用這些位置信息,因此具有更準(zhǔn)確的錯(cuò)誤定位功能。進(jìn)一步地,本發(fā)明通過對(duì)源代碼的抽象語(yǔ)法樹進(jìn)行分析,具有充分的語(yǔ)義信息來(lái)判斷潛在的數(shù)組越界錯(cuò)誤的類型,并相應(yīng)地進(jìn)行源代碼變換,減少了插入代碼段的規(guī)模,簡(jiǎn)化了插入代碼段的復(fù)雜程度,從而獲得了更好的運(yùn)行時(shí)效率和性能。進(jìn)一步地,本發(fā)明通過對(duì)用戶自定義檢測(cè)策略和校正策略的集成和源代碼變換,使得軟件具有更自動(dòng)化的運(yùn)行時(shí)錯(cuò)誤校正功能。
      [0070]本發(fā)明附加的方面和優(yōu)點(diǎn)將在下面的描述中部分給出,這些將從下面的描述中變得明顯,或通過本發(fā)明的實(shí)踐了解到。
      【專利附圖】

      【附圖說明】
      [0071]圖1示出了根據(jù)本發(fā)明的數(shù)組越界錯(cuò)誤的自動(dòng)檢測(cè)和校正方法的流程示意圖?!揪唧w實(shí)施方式】
      [0072]下面詳細(xì)描述本發(fā)明的實(shí)施方式,所述實(shí)施方式的示例在附圖中示出,其中自始至終相同或類似的標(biāo)號(hào)表示相同或類似的元件或具有相同或類似功能的元件。下面通過參考附圖描述的實(shí)施方式是示例性的,僅用于解釋本發(fā)明,而不能解釋為對(duì)本發(fā)明的限制。
      [0073]本【技術(shù)領(lǐng)域】技術(shù)人員可以理解的是,除非特意聲明,這里使用的單數(shù)形式“一”、“一個(gè)”、“所述”和“該”也可包括復(fù)數(shù)形式。應(yīng)該進(jìn)一步理解的是,本發(fā)明的說明書中使用的措辭“包括”是指存在所述特征、整數(shù)、步驟、操作、元件和/或組件,但是并不排除存在或添加一個(gè)或多個(gè)其他特征、整數(shù)、步驟、操作、元件、組件和/或它們的組。應(yīng)該理解,當(dāng)我們稱元件被“連接”或“耦接”到另一元件時(shí),它可以直接連接或耦接到其他元件,或者也可以存在中間元件。此外,這里使用的“連接”或“耦接”可以包括無(wú)線連接或耦接。這里使用的措辭“和/或”包括一個(gè)或更多個(gè)相關(guān)聯(lián)的列出項(xiàng)的任一單元和全部組合。
      [0074]本【技術(shù)領(lǐng)域】技術(shù)人員可以理解的是,除非另外定義,這里使用的所有術(shù)語(yǔ)(包括技術(shù)術(shù)語(yǔ)和科學(xué)術(shù)語(yǔ))具有與本發(fā)明所屬領(lǐng)域中的普通技術(shù)人員的一般理解相同的意義。還應(yīng)該理解的是,諸如通用字典中定義的那些術(shù)語(yǔ)應(yīng)該被理解為具有與現(xiàn)有技術(shù)的上下文中的意義一致的意義,并且除非像這里一樣定義,不會(huì)用理想化或過于正式的含義來(lái)解釋。
      [0075]下文將對(duì)上述各步驟具體展開描述。圖1示出了根據(jù)本發(fā)明的數(shù)組越界錯(cuò)誤的自動(dòng)檢測(cè)和校正方法的流程示意圖。如圖1所示,本發(fā)明的目的是通過下述技術(shù)方案實(shí)現(xiàn)的,具體操作步驟如下:
      [0076]步驟Sll:選擇待變換的源代碼項(xiàng)目目錄,或者單個(gè)源代碼文件。
      [0077]步驟S12:針對(duì)待變換的源代碼,利用編譯器生成源代碼的符號(hào)表和抽象語(yǔ)法樹。
      [0078]步驟S13:遍歷抽象語(yǔ)法樹中的所有結(jié)點(diǎn),構(gòu)造指針依賴圖,并進(jìn)行源代碼變換計(jì)

      ο
      [0079]其中,指針依賴圖是一個(gè)有向圖二元組(V,E),其中V是源代碼中的指針集合(也是圖的結(jié)點(diǎn)集合),E是源代碼中的指針依賴關(guān)系集合(也是圖的有向邊集合)。當(dāng)指針對(duì)(P,q)存在于指針依賴圖中,或者存在一條從P到q的有向路徑時(shí),指針q是指針P的依賴指針,即表示指針P所指向的數(shù)組就是指針q所指向的數(shù)組。當(dāng)指針q是指針P的依賴指針,并且指針q沒有依賴指針時(shí),指針q是指針P的最終依賴指針。對(duì)于指針P,可以通過如下方法獲取其最終依賴指針:在指針依賴圖中,從P開始沿有向邊往前遍歷,直到訪問到一個(gè)沒有后繼結(jié)點(diǎn)的指針q時(shí),Q就是P的最終依賴指針。
      [0080]本步驟具體來(lái)說,在遍歷抽象語(yǔ)法樹的過程中,對(duì)于當(dāng)前遍歷到的結(jié)點(diǎn)S,得到其所在的源文件名filename和代碼行號(hào)loc,并根據(jù)結(jié)點(diǎn)s的類型分別進(jìn)行如下操作:`[0081]步驟S131:如果結(jié)點(diǎn)s是一個(gè)帶初始值的指針聲明type*p=expr,其中p為指針名’ expr為表達(dá)式,且expr中包含一個(gè)支配指針q時(shí),將(P, q)作為一條邊加入指針依賴圖。其中,支配指針是指決定該表達(dá)式指向地址的主要指針變量,而該表達(dá)式的其他部分決定相對(duì)于該指針指向地址的偏移量。
      [0082]步驟S132:如果結(jié)點(diǎn)s是一個(gè)指針賦值表達(dá)式p=expr,其中p為指針名,expr為表達(dá)式,且expr中包含一個(gè)支配指針q時(shí),將(P,q)作為一條邊加入指針依賴圖。
      [0083]步驟S133:如果結(jié)點(diǎn)s是一個(gè)數(shù)組下標(biāo)表達(dá)式p[expr],其中p為指針名或數(shù)組名,expr為表達(dá)式時(shí),根據(jù)P的類型分別進(jìn)行如下操作:
      [0084]步驟S1331:當(dāng)P是符號(hào)表中已定義的一個(gè)數(shù)組時(shí),從符號(hào)表中獲取該數(shù)組的類型type和長(zhǎng)度len,然后將該表達(dá)式替換為如下函數(shù)調(diào)用:
      [0085]* ((type*)(—MNT_CHECK_AAV(p+expr, p, p+len, filename, loc)))
      [0086]其中,函數(shù)參數(shù)p+expr表示數(shù)組下標(biāo)表達(dá)式訪問的內(nèi)存地址,函數(shù)參數(shù)P表示數(shù)組的起始地址,函數(shù)參數(shù)P+len表示數(shù)組的結(jié)束地址,函數(shù)參數(shù)filename表示源文件名,函數(shù)參數(shù)1c表示代碼行號(hào);
      [0087]步驟S1332:當(dāng)p是所在函數(shù)聲明的第η個(gè)形式參數(shù)時(shí),從符號(hào)表中獲取該指針的類型type,然后將該表達(dá)式替換為如下函數(shù)調(diào)用:
      [0088]* ((type*) (__MNT_CHK_AAV(p+expr, __MNT_CHK_AAV_B_n, __MNT_CHK_AAV_E_n, filename, loc)))
      [0089]其中,函數(shù)參數(shù)p+expr表示數(shù)組下標(biāo)表達(dá)式訪問的內(nèi)存地址,函數(shù)參數(shù)—MNT_CHK_AAV_B_n表示第η個(gè)形式參數(shù)的起始地址,函數(shù)參數(shù)—MNT_CHK_AAV_E_n表示第η個(gè)形式參數(shù)的結(jié)束地址,函數(shù)參數(shù)filename表示源文件名,函數(shù)參數(shù)1c表示代碼行號(hào);
      [0090]步驟S1333:當(dāng)P是不滿足以上步驟S1331、步驟S1332中的兩種情況的指針時(shí),從指針依賴圖中獲取其最終依賴指針q。當(dāng)q不存在時(shí),認(rèn)為源代碼中存在指針使用前未賦初值的錯(cuò)誤,并報(bào)錯(cuò)。當(dāng)q存在時(shí),根據(jù)q的類型分別進(jìn)行如下操作:
      [0091]步驟S13331:當(dāng)q是符號(hào)表中已定義的一個(gè)數(shù)組時(shí),從符號(hào)表中獲取指針P的類型type和數(shù)組q的長(zhǎng)度len,然后將該表達(dá)式替換為如下函數(shù)調(diào)用:
      [0092]*((type*)(—MNT_CHECK_AAV(p+expr, q, q+len, filename, loc)))
      [0093]其中,函數(shù)參數(shù)p+expr表示數(shù)組下標(biāo)表達(dá)式訪問的內(nèi)存地址,函數(shù)參數(shù)q表示數(shù)組的起始地址,函數(shù)參數(shù)q+len表示數(shù)組的結(jié)束地址,函數(shù)參數(shù)filename表示源文件名,函數(shù)參數(shù)1c表示代碼行號(hào);
      [0094]步驟S13332:當(dāng)q是所在函數(shù)聲明的第η個(gè)形式參數(shù)時(shí),從符號(hào)表中獲取指針P的類型type,然后將該表達(dá)式替換為如下函數(shù)調(diào)用:
      [0095]* ((type*) (__MNT_CHK_AAV(p+expr, __MNT_CHK_AAV_B_n, __MNT_CHK_AAV_E_n, filename, loc)))
      [0096]其中,函數(shù)參數(shù)p+expr表示數(shù)組下標(biāo)表達(dá)式訪問的內(nèi)存地址,函數(shù)參數(shù)—MNT_CHK_AAV_B_n表示第η個(gè)形式參數(shù)的起始地址,函數(shù)參數(shù)—MNT_CHK_AAV_E_n表示第η個(gè)形式參數(shù)的結(jié)束地址,函數(shù)參數(shù)filename表示源文件名,函數(shù)參數(shù)1c表示代碼行號(hào);
      [0097]步驟S13333:當(dāng)q是不滿足以上步驟S13331、步驟S13332中的兩種情況的指針時(shí),認(rèn)為源代碼中存在指針使用前未賦初值的錯(cuò)誤,并報(bào)錯(cuò)。
      [0098]步驟S134:如果結(jié)點(diǎn)s是一個(gè)指針訪問表達(dá)式*expr,其中expr為表達(dá)式,且expr中包含一個(gè)支配指針P時(shí),根`據(jù)P的類型分別進(jìn)行如下操作:
      [0099]步驟S1341:當(dāng)P是符號(hào)表中已定義的一個(gè)數(shù)組時(shí),從符號(hào)表中獲取該數(shù)組的類型type和長(zhǎng)度len,然后將該表達(dá)式替換為如下函數(shù)調(diào)用:
      [0100]* ((type*)(—MNT_CHECK_AAV(expr, p, p+len, filename, loc)))
      [0101]其中,函數(shù)參數(shù)expr表示指針訪問表達(dá)式訪問的內(nèi)存地址,函數(shù)參數(shù)P表示數(shù)組的起始地址,函數(shù)參數(shù)P+len表示數(shù)組的結(jié)束地址,函數(shù)參數(shù)filename表示源文件名,函數(shù)參數(shù)1c表示代碼行號(hào);
      [0102]步驟S1342:當(dāng)P是所在函數(shù)聲明的第η個(gè)形式參數(shù)時(shí),從符號(hào)表中獲取該指針的類型type,然后將該表達(dá)式替換為如下函數(shù)調(diào)用:
      [0103]* ((type*) (__MNT_CHK_AAV(expr, __MNT_CHK_AAV_B_n, __MNT_CHK_AAV_E_n, filename, loc)))
      [0104]其中,函數(shù)參數(shù)expr表示指針訪問表達(dá)式訪問的內(nèi)存地址,函數(shù)參數(shù)—MNT_CHK_AAV_B_n表示第η個(gè)形式參數(shù)的起始地址,函數(shù)參數(shù)—MNT_CHK_AAV_E_n表示第η個(gè)形式參數(shù)的結(jié)束地址,函數(shù)參數(shù)filename表示源文件名,函數(shù)參數(shù)1c表示代碼行號(hào);
      [0105]步驟S1343:當(dāng)P是不滿足以上步驟S1341、步驟S1342中的兩種情況的指針時(shí),從指針依賴圖中獲取其最終依賴指針q。當(dāng)q不存在時(shí),認(rèn)為源代碼中存在指針使用前未賦初值的錯(cuò)誤,并報(bào)錯(cuò)。當(dāng)q存在時(shí),根據(jù)q的類型分別進(jìn)行如下操作:
      [0106]步驟S13431:當(dāng)q是符號(hào)表中已定義的一個(gè)數(shù)組時(shí),從符號(hào)表中獲取指針P的類型type和數(shù)組q的長(zhǎng)度len,然后將該表達(dá)式替換為如下函數(shù)調(diào)用:
      [0107]*((type*)(—MNT_CHECK_AAV(expr, q, q+len, filename, loc)))
      [0108]其中,函數(shù)參數(shù)expr表示指針訪問表達(dá)式訪問的內(nèi)存地址,函數(shù)參數(shù)q表示數(shù)組的起始地址,函數(shù)參數(shù)q+len表示數(shù)組的結(jié)束地址,函數(shù)參數(shù)filename表示源文件名,函數(shù)參數(shù)1c表示代碼行號(hào);
      [0109]步驟S13432:當(dāng)q是所在函數(shù)聲明的第η個(gè)形式參數(shù)時(shí),從符號(hào)表中獲取指針P的類型type,然后將該表達(dá)式替換為如下函數(shù)調(diào)用:
      [0110]* ((type*) (__MNT_CHK_AAV(expr, __MNT_CHK_AAV_B_n, __MNT_CHK_AAV_E_n, filename, loc)))
      [0111]其中,函數(shù)參數(shù)expr表示指針訪問表達(dá)式訪問的內(nèi)存地址,函數(shù)參數(shù)—MNT_CHK_AAV_B_n表示第η個(gè)形式參數(shù)的起始地址,函數(shù)參數(shù)—MNT_CHK_AAV_E_n表示第η個(gè)形式參數(shù)的結(jié)束地址,函數(shù)參數(shù)filename表示源文件名,函數(shù)參數(shù)1c表示代碼行號(hào);
      [0112]步驟S13433:當(dāng)q是不滿足以上步驟S13431、步驟S13432中的兩種情況的指針時(shí),認(rèn)為源代碼中存在指針使用前未賦初值的錯(cuò)誤,并報(bào)錯(cuò)。
      [0113]步驟S135:如果結(jié)點(diǎn)s是一個(gè)函數(shù)聲明或函數(shù)定義表達(dá)式type func (..., type_n expr_n,…),其中:第η個(gè)參數(shù)表達(dá)式expr_n為type_n類型的數(shù)組或指針聲明P,省略號(hào)…表示其它參數(shù)表達(dá)式時(shí),將該函數(shù)聲明或函數(shù)定義替換為如下函數(shù):
      [0114]type func(..., type_n expr_n, void*—MNT_CHK_AAV_B_n, void*—MNT_CHK_AAV_E_n,...)
      [0115]其中,省略號(hào)…表不原來(lái)的所有參數(shù)表達(dá)式,函數(shù)參數(shù)—MNT_CHK_AAV_B_n表不第η個(gè)參數(shù)表達(dá)式的起始地址,函數(shù)參數(shù)—MNT_CHK_AAV_E_n表示第η個(gè)參數(shù)表達(dá)式的結(jié)束地址;
      `[0116]步驟S136:如果結(jié)點(diǎn)s是一個(gè)函數(shù)調(diào)用表達(dá)式func (…,expr_n,…),其中--第η個(gè)參數(shù)表達(dá)式expr_n中包含一個(gè)支配指針p,省略號(hào)…表示其它參數(shù)表達(dá)式時(shí),根據(jù)P的類型分別進(jìn)行如下操作:
      [0117]步驟S1361:當(dāng)P是符號(hào)表中已定義的一個(gè)數(shù)組時(shí),從符號(hào)表中獲取該數(shù)組的長(zhǎng)度len,然后將該表達(dá)式替換為如下函數(shù)調(diào)用:func(...,expr_n, p, p+len,…),其中,省略號(hào)…表示原來(lái)的所有參數(shù)表達(dá)式,函數(shù)參數(shù)P表示數(shù)組的起始地址,函數(shù)參數(shù)p+len表示數(shù)組的結(jié)束地址;
      [0118]步驟S1362:當(dāng)P是所在函數(shù)聲明的第η個(gè)形式參數(shù)時(shí),將該表達(dá)式替換為如下函數(shù)調(diào)用:
      [0119]func (…,expr_n, —MNT_CHK_AAV_B_n, _MNT_CHK_AAV_E_n,…)
      [0120]其中,省略號(hào)…表示原來(lái)的所有參數(shù)表達(dá)式,函數(shù)參數(shù)—MNT_CHK_AAV_B_n表示第η個(gè)形式參數(shù)的起始地址,函數(shù)參數(shù)—MNT_CHK_AAV_E_n表示第η個(gè)形式參數(shù)的結(jié)束地址;
      [0121]步驟S1363:當(dāng)P是不滿足以上步驟S1361、步驟S1362中的兩種情況的指針時(shí),從指針依賴圖中獲取其最終依賴指針q。當(dāng)q不存在時(shí),認(rèn)為源代碼中存在指針使用前未賦初值的錯(cuò)誤,并報(bào)錯(cuò)。當(dāng)q存在時(shí),根據(jù)q的類型分別進(jìn)行如下操作:
      [0122]步驟S13631:當(dāng)q是符號(hào)表中已定義的一個(gè)數(shù)組時(shí),從符號(hào)表中獲取數(shù)組q的長(zhǎng)度len,然后將該表達(dá)式替換為如下函數(shù)調(diào)用:func(...,expr_n, q, q+len,…),其中,省略號(hào)…表示原來(lái)的所有參數(shù)表達(dá)式,函數(shù)參數(shù)q表示數(shù)組的起始地址,函數(shù)參數(shù)q+len表示數(shù)組的結(jié)束地址;[0123]步驟S13632:當(dāng)q是所在函數(shù)聲明的第η個(gè)形式參數(shù)時(shí),將該表達(dá)式替換為如下函數(shù)調(diào)用:
      [0124]func (…,expr_n, —MNT_CHK_AAV_B_n, _MNT_CHK_AAV_E_n,…)
      [0125]其中,省略號(hào)…表示原來(lái)的所有參數(shù)表達(dá)式,函數(shù)參數(shù)—MNT_CHK_AAV_B_n表示第η個(gè)形式參數(shù)的起始地址,函數(shù)參數(shù)—MNT_CHK_AAV_E_n表示第η個(gè)形式參數(shù)的結(jié)束地址;
      [0126]步驟S13633:當(dāng)q是不滿足以上步驟S13631、步驟S13632中的兩種情況的指針時(shí),認(rèn)為源代碼中存在指針使用前未賦初值的錯(cuò)誤,并報(bào)錯(cuò)。
      [0127]步驟S14:根據(jù)步驟S13的計(jì)算結(jié)果,在源代碼中將需替換的部分源代碼進(jìn)行替換,生成變換后的源代碼,并保存到新項(xiàng)目目錄或新文件。
      [0128]步驟S15:定義數(shù)組越界檢測(cè)策略和校正策略,并將這些策略轉(zhuǎn)化為函數(shù)—MNT_CHK_AAV的定義。其中,檢測(cè)策略是指:如何判斷對(duì)數(shù)組的訪問是否超出數(shù)組的內(nèi)存范圍。例如,一種可行的檢測(cè)策略為:判斷要訪問的地址P是否在允許的范圍[begin,end)之間,當(dāng)超出該范圍時(shí),報(bào)告數(shù)組越界錯(cuò)誤。該策略可以被轉(zhuǎn)化為如下源代碼:
      [0129]
      【權(quán)利要求】
      1.一種數(shù)組越界錯(cuò)誤的自動(dòng)檢測(cè)和校正方法,其特征在于,包括: 步驟1、選擇待變換的源代碼項(xiàng)目目錄,或者單個(gè)源代碼文件; 步驟2、針對(duì)待變換的源代碼,利用編譯器生成源代碼的符號(hào)表和抽象語(yǔ)法樹; 步驟3、遍歷抽象語(yǔ)法樹中的所有結(jié)點(diǎn),構(gòu)造指針依賴圖,并進(jìn)行源代碼變換計(jì)算,其中:所述指針依賴圖是一個(gè)有向圖二元組,所述有向圖二元組包括源代碼中的指針集合和源代碼中的指針依賴關(guān)系集合,所述源代碼中的指針集合構(gòu)成指針依賴圖中的結(jié)點(diǎn)集合,所述源代碼中的指針依賴關(guān)系集合構(gòu)成指針依賴圖中的有向邊集合; 步驟4、根據(jù)步驟3的計(jì)算結(jié)果,在源代碼中將需替換的部分源代碼進(jìn)行替換,生成變換后的源代碼,并保存到新項(xiàng)目目錄或新文件; 步驟5、定義數(shù)組越界檢測(cè)策略和校正策略,并將這些策略轉(zhuǎn)化為函數(shù)—MNT_CHK_AAV的定義,將按照策略生成的函數(shù)—MNT_CHK_AAV的定義寫入變換后源代碼的開頭部分;步驟6、將變換后的項(xiàng)目目錄或文件用原編譯器進(jìn)行編譯,生成目標(biāo)系統(tǒng)上的可執(zhí)行文件; 步驟7、將生成的可執(zhí)行文件部署到目標(biāo)系統(tǒng)并運(yùn)行,當(dāng)可執(zhí)行文件運(yùn)行到已替換或插入的代碼段時(shí),將自動(dòng)檢測(cè)和校正數(shù)組越界錯(cuò)誤,并準(zhǔn)確報(bào)告錯(cuò)誤對(duì)應(yīng)的源代碼位置。
      2.如權(quán)利要求1所述的數(shù)組越界錯(cuò)誤的自動(dòng)檢測(cè)和校正方法,其特征在于,所述遍歷抽象語(yǔ)法樹中 的所有結(jié)點(diǎn),構(gòu)造指針依賴圖,并進(jìn)行源代碼變換計(jì)算,進(jìn)一步包括: 在遍歷抽象語(yǔ)法樹的過程中,根據(jù)當(dāng)前遍歷到的結(jié)點(diǎn)s的類型進(jìn)行如下操作之一: 向指針依賴圖中加入指針依賴關(guān)系, 將數(shù)組下標(biāo)訪問表達(dá)式和指針訪問表達(dá)式替換為—MNT_CHK_AAV函數(shù)的調(diào)用, 將函數(shù)聲明、函數(shù)定義、函數(shù)調(diào)用表達(dá)式替換為新的表達(dá)式。
      3.如權(quán)利要求1所述的數(shù)組越界錯(cuò)誤的自動(dòng)檢測(cè)和校正方法,其特征在于,所述在遍歷抽象語(yǔ)法樹的過程中,根據(jù)當(dāng)前遍歷到的結(jié)點(diǎn)s的類型進(jìn)行如下操作之一:向指針依賴圖中加入指針依賴關(guān)系,將數(shù)組下標(biāo)訪問表達(dá)式和指針訪問表達(dá)式替換為—MNT_CHK_AAV函數(shù)的調(diào)用,將函數(shù)聲明、函數(shù)定義、函數(shù)調(diào)用表達(dá)式替換為新的表達(dá)式,進(jìn)一步包括: 在遍歷抽象語(yǔ)法樹的過程中,對(duì)于當(dāng)前遍歷到的結(jié)點(diǎn)S,得到其所在的源文件名filename和代碼行號(hào)loc,并根據(jù)當(dāng)前遍歷到的結(jié)點(diǎn)s的類型分別進(jìn)行如下操作: 操作1、如果結(jié)點(diǎn)s是一個(gè)帶初始值的指針聲明type*p=expr,其中p為指針名,expr為表達(dá)式,且expr中包含一個(gè)支配指針q,則將指針對(duì)(P,q)作為一條邊加入指針依賴圖;操作2、如果結(jié)點(diǎn)s是一個(gè)指針賦值表達(dá)式p=expr,其中p為指針名,expr為表達(dá)式,且expr中包含一個(gè)支配指針q,則將(P,q)作為一條邊加入指針依賴圖; 操作3、如果結(jié)點(diǎn)s是一個(gè)數(shù)組下標(biāo)表達(dá)式P [expr],其中p為指針名或數(shù)組名,expr為表達(dá)式,則根據(jù)P的類型分別進(jìn)行如下操作: 操作31、如果P是符號(hào)表中已定義的一個(gè)數(shù)組,則從符號(hào)表中獲取該數(shù)組的類型type和長(zhǎng)度len,然后將該表達(dá)式替換為如下函數(shù)調(diào)用:
      * ((type*)(—MNT_CHECK_AAV(p+expr, p, p+len, filename, loc))) 其中,函數(shù)參數(shù)p+expr表示數(shù)組下標(biāo)表達(dá)式訪問的內(nèi)存地址,函數(shù)參數(shù)P表示數(shù)組的起始地址,函數(shù)參數(shù)p+len表示數(shù)組的結(jié)束地址,函數(shù)參數(shù)filename表示源文件名,函數(shù)參數(shù)1c表示代碼行號(hào);操作32、如果P是所在函數(shù)聲明的第η個(gè)形式參數(shù),則從符號(hào)表中獲取該指針的類型type,然后將該表達(dá)式替換為如下函數(shù)調(diào)用: *((type*) (__MNT_CHK_AAV(p+expr, __MNT_CHK_AAV_B_n,__MNT_CHK_AAV_E_n, filename, loc))) 其中,函數(shù)參數(shù)p+expr表示數(shù)組下標(biāo)表達(dá)式訪問的內(nèi)存地址,函數(shù)參數(shù)—MNT_CHK_AAV_B_n表示第η個(gè)形式參數(shù)的起始地址,函數(shù)參數(shù)—MNT_CHK_AAV_E_n表示第η個(gè)形式參數(shù)的結(jié)束地址,函數(shù)參數(shù)filename表示源文件名,函數(shù)參數(shù)1c表示代碼行號(hào); 操作33、如果P是不滿足以上操作31、操作32中的兩種情況的指針,則從指針依賴圖中獲取其最終依賴指針q,如果q不存在,則認(rèn)為源代碼中存在指針使用前未賦初值的錯(cuò)誤,并報(bào)錯(cuò),如果q存在,則根據(jù)q的類型分別進(jìn)行如下操作: 操作331、如果q是符號(hào)表中已定義的一個(gè)數(shù)組,則從符號(hào)表中獲取指針P的類型type和數(shù)組q的長(zhǎng)度len,然后將該表達(dá)式替換為如下函數(shù)調(diào)用:
      *((type*)(—MNT_CHECK_AAV(p+expr, q, q+len, filename, loc))) 其中,函數(shù)參數(shù)p+expr表示數(shù)組下標(biāo)表達(dá)式訪問的內(nèi)存地址,函數(shù)參數(shù)q表示數(shù)組的起始地址,函數(shù)參數(shù)q+len表示數(shù)組的結(jié)束地址,函數(shù)參數(shù)filename表示源文件名,函數(shù)參數(shù)1c表示代碼行號(hào); 操作332、如果q是所在函數(shù)聲明的第η個(gè)形式參數(shù),則從符號(hào)表中獲取指針P的類型type,然后將該表達(dá)式替換為如下函數(shù)調(diào)用: *((type*) (__MNT_CHK_AAV(p+expr, __MNT_CHK_AAV_B_n,__MNT_CHK_AAV_E_n, filename, loc))) 其中,函數(shù)參數(shù)p+expr表示數(shù)組下標(biāo)表達(dá)式訪問的內(nèi)存地址,函數(shù)參數(shù)—MNT_CHK_AAV_B_n表示第η個(gè)形式參數(shù)的起始地址,函數(shù)參數(shù)—MNT_CHK_AAV_E_n表示第η個(gè)形式參數(shù)的結(jié)束地址,函數(shù)參數(shù)filename表示源文件名,函數(shù)參數(shù)1c表示代碼行號(hào); 操作333、如果q是不滿足以上操作331、操作332中的兩種情況的指針,則認(rèn)為源代碼中存在指針使用前未賦初值的錯(cuò)誤,并報(bào)錯(cuò); 操作4、如果結(jié)點(diǎn)s是一個(gè)指針訪問表達(dá)式*expr,其中expr為表達(dá)式,且expr中包含一個(gè)支配指針P,則根據(jù)P的類型分別進(jìn)行如下操作: 操作41、如果P是符號(hào)表中已定義的一個(gè)數(shù)組,則從符號(hào)表中獲取該數(shù)組的類型type和長(zhǎng)度len,然后將該表達(dá)式替換為如下函數(shù)調(diào)用:
      *((type*)(—MNT_CHECK_AAV(expr, p, p+len, filename, loc))) 其中,函數(shù)參數(shù)expr表示指針訪問表達(dá)式訪問的內(nèi)存地址,函數(shù)參數(shù)P表示數(shù)組的起始地址,函數(shù)參數(shù)p+len表示數(shù)組的結(jié)束地址,函數(shù)參數(shù)filename表示源文件名,函數(shù)參數(shù)1c表不代碼行號(hào); 操作42、如果P是所在函數(shù)聲明的第η個(gè)形式參數(shù),則從符號(hào)表中獲取該指針的類型type,然后將該表達(dá)式替換為如下函數(shù)調(diào)用: *((type*) (__MNT_CHK_AAV(expr, __MNT_CHK_AAV_B_n, __MNT_CHK_AAV_E_n, filename, loc))) 其中,函數(shù)參數(shù)expr表示指針訪問表達(dá)式訪問的內(nèi)存地址,函數(shù)參數(shù)—MNT_CHK_AAV_B_n表示第η個(gè)形式參數(shù)的起始地址,函數(shù)參數(shù)—MNT_CHK_AAV_E_n表示第η個(gè)形式參數(shù)的結(jié)束地址,函數(shù)參數(shù)filename表示源文件名,函數(shù)參數(shù)1c表示代碼行號(hào); 操作43、如果P是不滿足以上操作41、操作42中的兩種情況的指針,則從指針依賴圖中獲取其最終依賴指針q,如果q不存在,則認(rèn)為源代碼中存在指針使用前未賦初值的錯(cuò)誤,并報(bào)錯(cuò),如果q存在,則根據(jù)q的類型分別進(jìn)行如下操作: 操作431、如果q是符號(hào)表中已定義的一個(gè)數(shù)組,則從符號(hào)表中獲取指針P的類型type和數(shù)組q的長(zhǎng)度len,然后將該表達(dá)式替換為如下函數(shù)調(diào)用: *((type*)(—MNT_CHECK_AAV(expr, q, q+len, filename, loc))) 其中,函數(shù)參數(shù)expr表示指針訪問表達(dá)式訪問的內(nèi)存地址,函數(shù)參數(shù)q表示數(shù)組的起始地址,函數(shù)參數(shù)q+len表示數(shù)組的結(jié)束地址,函數(shù)參數(shù)filename表示源文件名,函數(shù)參數(shù)1c表不代碼行號(hào); 操作432、如果q是所在函數(shù)聲明的第η個(gè)形式參數(shù),則從符號(hào)表中獲取指針P的類型type,然后將該表達(dá)式替換為如下函數(shù)調(diào)用: *((type*) (__MNT_CHK_AAV(expr, __MNT_CHK_AAV_B_n, __MNT_CHK_AAV_E_n, filename, loc))) 其中,函數(shù)參數(shù)expr表示指針訪問表達(dá)式訪問的內(nèi)存地址,函數(shù)參數(shù)—MNT_CHK_AAV_B_n表示第η個(gè)形式參數(shù)的起始地址,函數(shù)參數(shù)—MNT_CHK_AAV_E_n表示第η個(gè)形式參數(shù)的結(jié)束地址,函數(shù)參數(shù)filename表示源文件名,函數(shù)參數(shù)1c表示代碼行號(hào); 操作433、如果q是不滿足以上操作431、操作432中的兩種情況的指針,則認(rèn)為源代碼中存在指針使用前未賦初值的錯(cuò)誤,并報(bào)錯(cuò); 操作5、如果結(jié)點(diǎn)s是一個(gè)函數(shù)聲明或函數(shù)定義表達(dá)式type func (..., type_nexpr_η,…),其中:第η個(gè)參數(shù)表達(dá)式expr_n為type_n類型的數(shù)組或指針聲明P,省略號(hào)…表示其它參數(shù)表達(dá)式,則將該函數(shù)聲明或函數(shù)定義替換為如下函數(shù):
      type func(…,type_n expr_n, void*__MNT_CHK_AAV_B_n, void*__MNT_CHK_AAV_E_n,…) 其中,省略號(hào)…表示原來(lái)的所有參數(shù)表達(dá)式,函數(shù)參數(shù)—MNT_CHK_AAV_B_n表示第η個(gè)參數(shù)表達(dá)式的起始地址,函數(shù)參數(shù)__MNT_CHK_AAV_E_n表示第η個(gè)參數(shù)表達(dá)式的結(jié)束地址; 操作6、如果結(jié)點(diǎn)s是一個(gè)函數(shù)調(diào)用表達(dá)式func(...,expr_n,…),其中:第η個(gè)參數(shù)表達(dá)式eXpr_n中包含一個(gè)支配指針ρ,省略號(hào)…表示其它參數(shù)表達(dá)式,則根據(jù)P的類型分別進(jìn)行如下操作: 操作61、如果P是符號(hào)表中已定義的一個(gè)數(shù)組,則從符號(hào)表中獲取該數(shù)組的長(zhǎng)度len,然后將該表達(dá)式替換為如下函數(shù)調(diào)用:func(...,expr_n, p, p+len,…),其中,省略號(hào)…表示原來(lái)的所有參數(shù)表達(dá)式,函數(shù)參數(shù)P表示數(shù)組的起始地址,函數(shù)參數(shù)p+len表示數(shù)組的結(jié)束地址; 操作62、如果P是所在函數(shù)聲明的第η個(gè)形式參數(shù),則將該表達(dá)式替換為如下函數(shù)調(diào)用:
      func (…,expr_n, —MNT_CHK_AAV_B_n, _MNT_CHK_AAV_E_n,…) 其中,省略號(hào)…表示原來(lái)的所有參數(shù)表達(dá)式,函數(shù)參數(shù)—MNT_CHK_AAV_B_n表示第η個(gè)形式參數(shù)的起始地址,函數(shù)參數(shù)—MNT_CHK_AAV_E_n表示第η個(gè)形式參數(shù)的結(jié)束地址;操作63、如果P是不滿足以上操作61、操作62中的兩種情況的指針,則從指針依賴圖中獲取其最終依賴指針q,如果q不存在,則認(rèn)為源代碼中存在指針使用前未賦初值的錯(cuò)誤,并報(bào)錯(cuò),如果q存在,則根據(jù)q的類型分別進(jìn)行如下操作: 操作631、如果q是符號(hào)表中已定義的一個(gè)數(shù)組,則從符號(hào)表中獲取數(shù)組q的長(zhǎng)度len,然后將該表達(dá)式替換為如下函數(shù)調(diào)用:func(...,expr_n, q, q+len,…),其中,省略號(hào)…表示原來(lái)的所有參數(shù)表達(dá)式,函數(shù)參數(shù)q表示數(shù)組的起始地址,函數(shù)參數(shù)q+len表示數(shù)組的結(jié)束地址; 操作632、如果q是所在函數(shù)聲明的第η個(gè)形式參數(shù),則將該表達(dá)式替換為如下函數(shù)調(diào)用:
      func (…,expr_n, —MNT_CHK_AAV_B_n, _MNT_CHK_AAV_E_n,…) 其中,省略號(hào)…表示原來(lái)的所有參數(shù)表達(dá)式,函數(shù)參數(shù)—MNT_CHK_AAV_B_n表示第η個(gè)形式參數(shù)的起始地址,函數(shù)參數(shù)—MNT_CHK_AAV_E_n表示第η個(gè)形式參數(shù)的結(jié)束地址;操作633、如果q是不滿足以上操作631、操作632中的兩種情況的指針,則認(rèn)為源代碼中存在指針使用前未賦初值的錯(cuò)誤,并報(bào)錯(cuò)。
      4.如權(quán)利要求1所述的數(shù)組越界錯(cuò)誤的自動(dòng)檢測(cè)和校正方法,其特征在于,所述步驟3進(jìn)一步包括: 在指針依賴圖中,從P開始沿有向邊往前遍歷,直到訪問到一個(gè)沒有后繼結(jié)點(diǎn)的指針q,那么q就是P的最終依賴指針。
      5.如權(quán)利要求1所述的數(shù)組越界錯(cuò)誤的自動(dòng)檢測(cè)和校正方法,其特征在于,所述步驟3進(jìn)一步包括: 支配指針是指決定該表達(dá)式指向地址的主要指針變量; 該表達(dá)式的其他部分決定相對(duì)于該指針指向地址的偏移量。
      6.如權(quán)利要求1所述的數(shù)組越界錯(cuò)誤的自動(dòng)檢測(cè)和校正方法,其特征在于,所述檢測(cè)策略包括: 判斷要訪問的地址P是否在允許的范圍[begin,end)之間,如果超出該范圍,則報(bào)告數(shù)組越界錯(cuò)誤。
      7.如權(quán)利要求1所述的數(shù)組越界錯(cuò)誤的自動(dòng)檢測(cè)和校正方法,其特征在于:所述校正策略包括: 當(dāng)合法的內(nèi)存范圍為[begin, end),大小為η時(shí), 如果訪問地址P為下越界,則將P和begin之間的偏移量進(jìn)行模η運(yùn)算,并被end減后作為映射的合法訪問地址; 如果訪問地址P為上越界,則將P和end之間的偏移量進(jìn)行模η運(yùn)算,并加上begin作為映射的合法訪問地址; 如果訪問地址P在[begin, end)范圍內(nèi),則不作任何計(jì)算。
      8.如權(quán)利要求1所述的數(shù)組越界錯(cuò)誤的自動(dòng)檢測(cè)和校正方法,其特征在于:所述步驟5進(jìn)一步包括: 檢測(cè)策略和校正策略直接通過源代碼的方式說明;或者, 使用特別定義的描述語(yǔ)言來(lái)說明,并通過語(yǔ)言自動(dòng)轉(zhuǎn)化工具自動(dòng)翻譯為源代碼。
      【文檔編號(hào)】G06F11/36GK103778061SQ201410022323
      【公開日】2014年5月7日 申請(qǐng)日期:2014年1月17日 優(yōu)先權(quán)日:2014年1月17日
      【發(fā)明者】陳哲, 李文明, 黃志球 申請(qǐng)人:南京航空航天大學(xué)
      網(wǎng)友詢問留言 已有0條留言
      • 還沒有人留言評(píng)論。精彩留言會(huì)獲得點(diǎn)贊!
      1