,使其利用轉(zhuǎn)換函數(shù)訪問(wèn)新版本靜態(tài)變量、局部變量和參數(shù)。也就是說(shuō),對(duì)待更新函數(shù)舊版本內(nèi)容進(jìn)行改造,將待更新函數(shù)舊版本內(nèi)容訪問(wèn)的待更新數(shù)據(jù)都使用轉(zhuǎn)換函數(shù)(即適配器函數(shù))間接訪問(wèn)。中間輔助函數(shù)中待更新函數(shù)舊版本內(nèi)容則是通過(guò)讀寫(xiě)適配函數(shù)的方式來(lái)訪問(wèn)新版本數(shù)據(jù)(包括靜態(tài)變量、局部變量和參數(shù))。
[0074](4)根據(jù)用戶的初始化請(qǐng)求,將步驟(2)中生成的初級(jí)動(dòng)態(tài)升級(jí)補(bǔ)丁注入到正在運(yùn)行的待更新程序中;
[0075](5)注入動(dòng)態(tài)升級(jí)補(bǔ)丁后,根據(jù)待更新函數(shù)符號(hào)名和待更新靜態(tài)變量符號(hào)名獲得待更新程序中對(duì)應(yīng)的待更新函數(shù)和待更新靜態(tài)變量地址;
[0076](6)根據(jù)用戶發(fā)出的更新請(qǐng)求,暫停所有與更新相關(guān)的進(jìn)程,并根據(jù)獲取的待更新靜態(tài)變量地址對(duì)待更新靜態(tài)變量進(jìn)行更新;同時(shí),查看待更新函數(shù)是否位于函數(shù)調(diào)用棧,若是,則利用中間輔助函數(shù)對(duì)位于函數(shù)調(diào)用棧的待更新函數(shù)進(jìn)行更新;否則直接對(duì)未在函數(shù)調(diào)用棧的待更新函數(shù)進(jìn)行更新;本步驟包括下列子步驟:
[0077](6-1)根據(jù)用戶發(fā)出的更新請(qǐng)求,暫停所有與更新相關(guān)的進(jìn)程,將所有的舊版本待更新靜態(tài)變量轉(zhuǎn)換成新版本靜態(tài)變量;對(duì)于靜態(tài)變量的更新,通過(guò)一般類型,指針類型,數(shù)組類型三種不同的類型分別實(shí)現(xiàn)三種不同的轉(zhuǎn)換函數(shù),將舊版本待更新靜態(tài)變量轉(zhuǎn)換成新版本靜態(tài)變量;
[0078](6-2)查看待更新函數(shù)是否位于函數(shù)調(diào)用棧,若是,根據(jù)步驟(3)的函數(shù)語(yǔ)義映射表,修改線程當(dāng)前執(zhí)行位置后的下一條二進(jìn)制指令,將線程當(dāng)前執(zhí)行位置入棧,然后跳轉(zhuǎn)到步驟(3)中生成中間輔助函數(shù)的入口地址,利用中間輔助函數(shù)進(jìn)行更新;否則,對(duì)于未處于函數(shù)調(diào)用棧的待更新函數(shù),使用修改函數(shù)入口地址的方法進(jìn)行更新。
[0079]使用修改函數(shù)入口地址的方法更新未處于函數(shù)調(diào)用棧的待更新函數(shù)。當(dāng)程序運(yùn)行到待更新函數(shù)時(shí),直接跳轉(zhuǎn)到對(duì)應(yīng)的新版本函數(shù)進(jìn)行更新。具體而言,將待更新函數(shù)開(kāi)頭的二進(jìn)制代碼替換成jmp指令,使執(zhí)行路徑跳轉(zhuǎn)到新版本函數(shù),函數(shù)的參數(shù)和局部變量則采用重定向的方式映射到新版本函數(shù)的內(nèi)存地址。
[0080]對(duì)處于函數(shù)調(diào)用棧的待更新函數(shù),修改線程當(dāng)前執(zhí)行位置后的下一條執(zhí)行指令,使其跳轉(zhuǎn)到中間輔助函數(shù)來(lái)完成更新正在調(diào)用的函數(shù)。具體將待更新函數(shù)當(dāng)前執(zhí)行位置下一條(一般情況為順序下一條,如果當(dāng)前指令為跳轉(zhuǎn)指令,則為跳轉(zhuǎn)的目標(biāo)地址)的二進(jìn)制指令替換成jmp指令,使執(zhí)行路徑跳轉(zhuǎn)到中間輔助函數(shù)。函數(shù)的參數(shù)和局部變量則采用重定向的方式映射到中間輔助函數(shù)的內(nèi)存地址,同時(shí)將線程當(dāng)前執(zhí)行位置記錄到中間輔助函數(shù)的堆棧中。
[0081](7)恢復(fù)因更新而被暫停的進(jìn)程,更新過(guò)程結(jié)束。
[0082]本發(fā)明方法還包括:在更新過(guò)程中發(fā)生錯(cuò)誤時(shí),通過(guò)監(jiān)控程序使其回滾到更新前的狀態(tài)。具體包括:
[0083](I)在程序更新前保存待更新程序的檢查點(diǎn);
[0084](2)在更新過(guò)程中,通過(guò)監(jiān)控程序?qū)崟r(shí)監(jiān)控待更新程序狀態(tài),若待更新程序發(fā)生異常時(shí),使用所述檢查點(diǎn)進(jìn)行回滾,將其還原到更新之前的狀態(tài)。
[0085]圖2所示為與上述方法對(duì)應(yīng)的一種基于中間輔助函數(shù)的軟件動(dòng)態(tài)升級(jí)系統(tǒng),所述系統(tǒng)包括:
[0086]整合模塊,用于獲取并整合舊版本代碼源文件和新版本代碼源文件,得到整合后的舊版本代碼源文件和新版本代碼源文件;
[0087]補(bǔ)丁生成模塊,用于通過(guò)對(duì)比整合后的舊版本代碼源文件和新版本代碼源文件,生成初級(jí)動(dòng)態(tài)升級(jí)補(bǔ)??;
[0088]分析模塊,用于靜態(tài)分析對(duì)比整合后的舊版本代碼源文件和新版本代碼源文件中的待更新函數(shù),分析待更新函數(shù)的語(yǔ)義,生成函數(shù)語(yǔ)義映射表,同時(shí)用于根據(jù)待更新函數(shù),生成中間輔助函數(shù);
[0089]所述分析模塊具體包括:
[0090]第一分析生成單元,用于分析待更新函數(shù)的語(yǔ)義,獲取并記錄待更新函數(shù)的安全更新指令集合,生成函數(shù)語(yǔ)義映射表;其中,安全更新指令集合是指若一段指令中任意一條指令前的所有執(zhí)行路徑都能保證新舊版本語(yǔ)義一致,則該段指令為安全更新指令集合。
[0091]第二分析生成單元,用于將待更新函數(shù)的參數(shù)作為中間輔助函數(shù)的參數(shù),構(gòu)造生成中間輔助函數(shù),所述中間輔助函數(shù)包含控制內(nèi)容、待更新函數(shù)新版本內(nèi)容和待更新函數(shù)舊版本內(nèi)容;其中,
[0092]所述控制內(nèi)容用于將待更新函數(shù)舊版本的局部變量和參數(shù)轉(zhuǎn)換成新版本的局部變量和參數(shù),還用于根據(jù)運(yùn)行時(shí)線程執(zhí)行地址來(lái)判斷該線程是否處于安全更新指令集合,若是,則跳轉(zhuǎn)入待更新函數(shù)新版本內(nèi)容,執(zhí)行待更新函數(shù)新版本內(nèi)容后返回;否則,跳轉(zhuǎn)入待更新函數(shù)舊版本內(nèi)容,當(dāng)執(zhí)行到安全更新指令集合中任意一條指令,則跳轉(zhuǎn)入待更新函數(shù)新版本內(nèi)容;
[0093]修改單元,用于對(duì)所述中間輔助函數(shù)的待更新函數(shù)舊版本內(nèi)容進(jìn)行修改,使其利用轉(zhuǎn)換函數(shù)訪問(wèn)新版本數(shù)據(jù)。
[0094]注入模塊,用于根據(jù)用戶的初始化請(qǐng)求,將生成的初級(jí)動(dòng)態(tài)升級(jí)補(bǔ)丁注入到正在運(yùn)行的待更新程序中;
[0095]獲取模塊,用于在注入動(dòng)態(tài)升級(jí)補(bǔ)丁后,根據(jù)待更新函數(shù)符號(hào)名和待更新靜態(tài)變量符號(hào)名獲得待更新程序中對(duì)應(yīng)的待更新函數(shù)和待更新靜態(tài)變量地址;
[0096]更新模塊,用于根據(jù)用戶發(fā)出的更新請(qǐng)求,暫停所有與更新相關(guān)的進(jìn)程,并根據(jù)獲取的待更新靜態(tài)變量地址對(duì)待更新靜態(tài)變量進(jìn)行更新;同時(shí),查看待更新函數(shù)是否位于函數(shù)調(diào)用棧,若是,則利用中間輔助函數(shù)對(duì)位于函數(shù)調(diào)用棧的待更新函數(shù)進(jìn)行更新;否則直接對(duì)未在函數(shù)調(diào)用棧的待更新函數(shù)進(jìn)行更新;
[0097]所述更新模塊具體包括:
[0098]暫停單元,用于根據(jù)用戶發(fā)出的更新請(qǐng)求,暫停所有與更新相關(guān)的進(jìn)程;
[0099]靜態(tài)變量更新單元,用于將所有的舊版本待更新靜態(tài)變量轉(zhuǎn)換成新版本靜態(tài)變量;
[0100]函數(shù)更新單元,用于查看待更新函數(shù)是否位于函數(shù)調(diào)用棧,若是,根據(jù)所述函數(shù)語(yǔ)義映射表,修改線程當(dāng)前執(zhí)行位置后的下一條二進(jìn)制指令,將線程當(dāng)前執(zhí)行位置入棧,然后跳轉(zhuǎn)到生成中間輔助函數(shù)的入口地址;否則,對(duì)于未處于函數(shù)調(diào)用棧的待更新函數(shù),使用修改函數(shù)入口地址的方法進(jìn)行更新。
[0101]恢復(fù)模塊,用于恢復(fù)因更新而被暫停的進(jìn)程,更新過(guò)程結(jié)束。
[0102]作為進(jìn)一步優(yōu)選的,所述系統(tǒng)還包括:
[0103]存儲(chǔ)模塊,用于在程序更新前保存待更新程序的檢查點(diǎn);
[0104]監(jiān)控模塊,用于在更新過(guò)程中,通過(guò)監(jiān)控程序?qū)崟r(shí)監(jiān)控待更新程序狀態(tài);
[0105]回滾模塊,用于在待更新程序發(fā)生異常時(shí),使用所述存儲(chǔ)模塊中保存的檢查點(diǎn)進(jìn)行回滾,將所述待更新程序還原到更新之前的狀態(tài)。
[0106]如圖3所示,在更新過(guò)程中,一些更新位置是能夠保證新函數(shù)中有與之對(duì)應(yīng)安全更新的位置,如更新點(diǎn)a,c。但是在一些更新位置,新函數(shù)中是沒(méi)有與之對(duì)應(yīng)的安全更新位置的,例如更新點(diǎn)b。如果在非安全更新位置強(qiáng)行更新的話,會(huì)導(dǎo)致函數(shù)fun會(huì)執(zhí)行兩次,從而導(dǎo)致各種不可知的錯(cuò)誤。經(jīng)過(guò)分析,當(dāng)更新點(diǎn)之前所有分支的新舊版本函數(shù)執(zhí)行路徑都語(yǔ)義一致時(shí),此時(shí)更新時(shí)不會(huì)發(fā)生因?yàn)檎Z(yǔ)句遺漏執(zhí)行或者多余執(zhí)行導(dǎo)致的更新不安全行為。在實(shí)際中,安全更新位置往往是連續(xù)的,所以可以把其變成范圍的方式記錄下來(lái),形成函數(shù)語(yǔ)義映射表。這樣就可以通過(guò)查詢函數(shù)語(yǔ)義映射表,可以判斷一個(gè)運(yùn)行位置是否為安全更新位置,也可以通過(guò)查詢函數(shù)語(yǔ)義映射表獲得任意一個(gè)安全位置對(duì)應(yīng)的跳轉(zhuǎn)位置。
[0107]中間輔助函數(shù)的構(gòu)造如圖4所示,首先將舊版本局部變量和參數(shù)轉(zhuǎn)換成新版本局部變量和參數(shù),然后從棧中獲得函數(shù)當(dāng)前執(zhí)行地址,查詢步驟(3-1)中的函數(shù)語(yǔ)義映射表,來(lái)判斷線程當(dāng)前執(zhí)行地址的指令是否處于安全更新指令集合,若函數(shù)當(dāng)前執(zhí)行地址的指令處于安全更新指令集合,可以通過(guò)步驟(3-1)中的函數(shù)語(yǔ)義映射表得到函數(shù)當(dāng)前執(zhí)行的地址在中間輔助函數(shù)中待更新函數(shù)新版本內(nèi)容對(duì)應(yīng)的位置,然后跳轉(zhuǎn)到該位置。若函數(shù)當(dāng)前執(zhí)行地址不處于安全更新指令集合,則跳轉(zhuǎn)入中間輔助函數(shù)中待更新函數(shù)舊版本內(nèi)容對(duì)應(yīng)位置。中間輔助函數(shù)接下來(lái)的部分是完整的新版本的待更新函數(shù)和經(jīng)過(guò)改造后的舊版本待更新函數(shù)。待更新函數(shù)舊版本內(nèi)容進(jìn)入安全更新指令集合(包括順序進(jìn)入,通過(guò)分支、循環(huán)、跳轉(zhuǎn)進(jìn)入)的語(yǔ)句后加入跳轉(zhuǎn)語(yǔ)句,使其跳轉(zhuǎn)到中間輔助函數(shù)待更新函數(shù)新版本內(nèi)容對(duì)應(yīng)部分。在更新過(guò)程中,假設(shè)函數(shù)更新情況如圖2所示,函數(shù)當(dāng)前執(zhí)行語(yǔ)句Statement4時(shí),跳轉(zhuǎn)到中間輔助函數(shù)后,查詢語(yǔ)句statement4為非安全位置,所以跳轉(zhuǎn)到待更新