一種調試時代碼動態更新方法
2023-06-25 19:04:56 1
一種調試時代碼動態更新方法
【專利摘要】本發明公開了一種調試時代碼動態更新方法,在軟體開發者調試程序時能夠立即更新自己代碼的方法,包括以下步驟:步驟一、軟體開發者使用調試器調試代碼;步驟二、軟體開發者在調試時更改代碼並保存,觸發準備更新過程,激活代碼檢測模塊;編寫遷移器模板類,完成遷移器模板類的修改,將更新信息傳入虛擬機中;步驟三、調試器請求虛擬機完成代碼更新。本發明通過擴展現有的調試器,增加了代碼檢測模塊、編譯模塊、以及狀態遷移器生成模塊等部件,在此基礎上建立了調試時動態更新代碼的系統,並且保證了代碼更新過程中的正確性。
【專利說明】一種調試時代碼動態更新方法
【技術領域】
[0001]本發明公開了一種調試時代碼動態更新方法,屬於軟體調試【技術領域】。
【背景技術】
[0002]軟體調試是重現軟體故障、定位故障根源,並最終解決軟體問題的過程。調試器是用來提供調試功能的軟體或硬體工具。在軟體開發的過程中,調試技術是必不可少的技術,一般來說主要的調試命令包括:設定斷點,單步執行,觀測對象和觀測堆棧信息,對於調試器的熟練使用會大大提高軟體的開發效率。
[0003]當調試一個項目代碼時,單步執行到錯誤點時,需要修改代碼,修改的代碼可能是各種各樣的類型,這時候如果想繼續調試代碼,傳統的方法是要重啟項目,然後再單步執行到上一次調試現場,這會消耗很多時間以及增加很多重複的操作,使得軟體開發的效率降低。
[0004]動態更新是從舊的版本更新到新版本的過程。圖3是JavaEmailServer從1.3.1版本到1.3.2版本的更新實例,可以從圖3中版本a和版本b看出三類變化:第一,是1adUser方法體的變化,第二,是setForwardedAddresses方法的參數發生了變化,第三是 User 類的域 forwardAddresses 從 String []變化到 EmailAddress []。在這三種變化中,對於第三種類的域發生改變的更新類型,當更新類的實例時,一般的做法是將新類中的新增加的域初始化為系統默認的初值(比如整型初始化為0,引用初始化為null)。在這個例子中,如果User實例採用系統默認值的更新,新版本的域forwardAddresses就會被初始化為null,但是從新舊版本的對比中可以看出如果要保持更新前後實例的正確,需要將String[]類型轉化為EmailAddress []類型,這時候就需要使用遷移函數,將User實例中的String[]的forwardAddresses轉換為新EmailAddress[]類型。從這個例子可以看出,對於一些更新類型,為了保證代碼更新的正確性,必須提供特定的遷移器來完成更新。
[0005]現有技術中常用的調試軟體包括以下幾種:
I)Hotswap:虛擬機本身也支持簡單的代碼更新,從JDK1.4版本開始存在的調試時動態更新的方法,被稱為Hotswap功能,這個功能的局限性在於只支持調試時刻對方法體的改變的更新,這樣的更新在調試時是遠遠不夠的,並不能滿足所有的更新類型。
[0006]2) DCE VM:能支持任意更新的類型,但是在更新的時候,只提供默認的遷移器,也就是在對象更新的時候將新增的域初始化為系統默認的初值,從上面對圖3的例子可以看出這樣的更新是不正確的,缺少提供遷移器來供軟體開發者參與修改,從而保證更新的正確性。
[0007]3)JRebel:一個商業的軟體,官方文檔沒有具體說明具體的支持的動態更新機制,只是說明JRebel不是從JVM本身出發,而是監控類的字節碼文件,通過字節碼文件和類加載器來完成更新,不支持通過修改JVM來實現代碼的更新。
【發明內容】
[0008]本發明所要解決的技術問題是:針對現有技術的缺陷,提供一種調試時代碼動態更新方法,具體是提供一種代碼在線更新的方法,使得被更新的程序不需要重新啟動即可更新代碼,同時提供了對於特定更新類型所需要的遷移器,保證代碼更新的正確性。
[0009]本發明為解決上述技術問題採用以下技術方案:
一種調試時代碼動態更新方法,包括以下步驟:
步驟一、軟體開發者使用調試器調試代碼;
步驟二、軟體開發者在調試時更改代碼並保存,觸發準備更新過程,包括代碼檢測,生成遷移器模板類,完成遷移器模板類的修改,將更新信息傳入虛擬機中;
步驟三、調試器請求虛擬機完成代碼更新。
[0010]作為本發明的進一步優選方案,步驟二中所述準備更新過程的具體步驟是:
21)軟體開發者使用調試器對程序進行調試,通過設斷點進行單步調試;
22)調試器監聽調試時代碼發生改變的事件,當代碼發生改變時,響應代碼改變的事件,再通過檢測獲取當前調試代碼類文件所在位置,獲取更改代碼之後的類文件以及更改之前的類文件,將新舊代碼類文件存放到臨時文夾中;
23)編譯存放於臨時文件夾中的新舊代碼類文件,得到對應新舊代碼類文件的字節碼文件;
24)通過比較新舊代碼的字節碼文件得到更新說明文件,進而得到更新類型信息;
25)判斷是否需要遷移器來完成代碼更新,
當不需要時轉入步驟26),否則轉入27);
26)判斷代碼更新不需要遷移器,完成代碼更新過程;
27)判斷代碼更新需要遷移器,生成一個遷移器模板;
28)軟體開發者修改遷移器模板類中的代碼並保存,編譯修改後的遷移器模板類;
29)通知調試器完成對遷移器模板類的修改,更新根據遷移器模板類生成的遷移器類,將遷移器類傳入虛擬機。
[0011]作為本發明的進一步優選方案,步驟24)中,所述新舊版本字節碼文件的比較包括:方法體的變化、類的方法增加或刪除、類域的增加或刪除、類結構的變化。
[0012]作為本發明的進一步優選方案,步驟27)中,所述遷移器模板包括下述組成部分:
401、定義的域,一個模板類重定義了新類的所有域,使得在模板的方法中可以自由訪問要遷移的對象的各個域;
402、對象遷移方法,為實例方法,用以訪問舊類對象的域;
403、類遷移方法,為靜態方法,用以在更新後對類的第一次訪問中被調用,實現更新靜態域;
404、父類,當所述父類發生更新時,模板類將聲明該父類。
[0013]作為本發明的進一步優選方案,所述步驟28 )中,軟體開發者根據前後代碼的不同來修改遷移器的模板類文件,保存修改後的遷移器模板類,編譯遷移器模板類得到遷移器模板類的字節碼文件。
[0014]作為本發明的進一步優選方案,所述步驟29)的具體步驟包括:
29-1)通過遷移器模板類生成遷移器類,將多個模板類合併成一個遷移器類;
29-2)將合併後的遷移器類所在的位置信息通過消息發送到虛擬機,虛擬機端接收遷移器類,完成更新的準備工作。
[0015]作為本發明的進一步優選方案,所述步驟三的具體步驟包括:
31)調試器在更新準備工作完成後,調用JVMTI中的RedefineClasses接口用修改後的類替換原始的類,首先在堆中找到舊類,找到後懸掛正在執行的程序,通知類加載器加載新類的修改後的版本,通過調用遷移類中對應的遷移方法來實現對該類實例的更新;
32)通過調用JVMTI提供的PopFrame接口使JVM重新執行被修改的方法,恢復現場。
[0016]作為本發明的進一步優選方案,所述調試器的調試代碼為Java代碼。
[0017]作為本發明的進一步優選方案,步驟21)中,所述單步調試的調試命令包括設斷點、單步執行、條件執行、監視對象或者監視堆棧。
[0018]作為本發明的進一步優選方案,所述虛擬機為Javelus。
[0019]本發明採用以上技術方案與現有技術相比,具有以下技術效果:能夠支持任意類型的更新;提供遷移器來供軟體開發者參與修改,從而保證更新的正確性;以修改JVM來支持代碼的更新。本發明所公開的方法支持在調試時修改代碼,無需重新啟動,使得修改的代碼能夠動態的更新。
【專利附圖】
【附圖說明】
[0020]圖1為本發明的系統結構以及交互順序示意圖。
[0021]圖2為調試器調試時代碼更新的執行流程示意圖。
[0022]圖3 為 JavaEmailServer 兩個版本的 User 和 Configurat1nManager 類的變化對比示意圖。
[0023]圖4為本發明生成的遷移器類模板示意圖。
[0024]圖5為本發明的一個具體實施例,軟體開發者對遷移器類模板做出的修改示例。
【具體實施方式】
[0025]下面詳細描述本發明的實施方式,所述實施方式的示例在附圖中示出,其中自始至終相同或類似的標號表示相同或類似的元件或具有相同或類似功能的元件。下面通過參考附圖描述的實施方式是示例性的,僅用於解釋本發明,而不能解釋為對本發明的限制。
[0026]下面結合附圖對本發明的技術方案做進一步的詳細說明:
本發明所基於的虛擬機是Javelus, Javelus是基於Hotspot VM實現了軟體運行時刻的動態更新系統。在Hotspot VM虛擬機體系中,調試器通過調用虛擬機提供的JVMTI來獲取虛擬機運行時刻的信息,本發明是將虛擬機中JVMTI原有的Hotswap功能(對應於RedefineClasses接口)進行擴展,支持任意更新種類,並且加入了遷移器來完成更新。
[0027]本發明的系統結構以及交互順序示意圖如圖1所示,所述的調試時動態更新代碼的方法,它包含以下步驟:
1)軟體開發者使用調試器調試Java代碼;
2)軟體開發者在調試時更改代碼並保存,觸發準備更新過程,包括代碼檢測,判斷是否需要編寫需要的遷移器模板類,完成遷移器模板類的修改,將更新信息傳入虛擬機中;
3)調試器請求虛擬機完成代碼更新,繼續調試。
[0028]調試器調試時代碼更新的執行流程示意圖如圖2所示,步驟2)軟體開發者在調試時更改代碼並保存,觸發準備更新過程,激活代碼檢測模塊、判斷是否需要編寫需要的遷移器模板類,完成遷移器模板類的修改,將更新信息傳入虛擬機中的具體步驟是:
21)軟體開發者在使用調試器對程序調試時,往往通過設斷點來單步調試,常用的調試命令是設斷點、單步執行,條件執行,監視對象、監視堆棧等。
[0029]22)調試器在調試程序時,同時監聽調試時代碼發生改變的事件,當被調試程序代碼發生改變時,會響應代碼改變的事件,接著調試器通過檢測獲取當前調試代碼類文件所在位置,獲取更改代碼之後的類文件以及更改之前的類文件,將新舊代碼類文件存放到臨時文夾中;
23)編譯新舊代碼類文件,得到對應新舊代碼類文件的字節碼文件;
24)通過比較新舊代碼的字節碼文件可以得到更新說明文件,得到的更新類型信息;
25)判斷是否需要遷移器來完成代碼更新,如果不需要轉到26),否則轉到27);
26)判斷代碼更新不需要遷移器,完成準備工作;
27)判斷代碼更新需要遷移器,生成遷移器模板類;
28)軟體開發者修改遷移器模板類中的代碼並保存,編譯修改的遷移器模板類;
29)通知調試器完成對遷移器模板類的修改,更新根據遷移器模板類生成更新所需要的遷移器類,將遷移器類傳入虛擬機。
[0030]步驟24)中,通過比較新舊版本字節碼文件得到更新的具體步驟是:比較新舊版本字節碼文件中的不同,具體來說有方法體的變化,類的方法增加或刪除,類域的增加或刪除,類結構發生變化。所獲取的變化類型可以是以上變化類型的組合。
[0031]步驟27)中,遷移器模板類生成的具體步驟是:根據新舊版本字節碼文件的比較可以得到新類中具體域的增加或刪除,生成一個模板類文件,一個類遷移器模板類包含四個主要部分:
1.定義的域:一個模板類重定義了新類的所有域,這樣在接下來模板的方法中可以自由訪問要遷移的對象的各個域;
2.對象遷移方法:該方法是實例方法,可以訪問舊類對象的域;
3.類遷移方法:該方法是靜態方法,在更新後對類的第一次訪問中被調用,用於更新靜態域;
4.父類:如果父類發生更新,則模板類會聲明該父類。
[0032]根據圖3所示的例子,本方法得到的遷移器模板類如圖4所示。
[0033]步驟28)中,軟體開發者可以根據前後代碼的不同來修改遷移器的模板類文件,根據圖3所示的例子步驟26生成了圖4的模板類,這時可以根據圖3例子中的變化寫出圖5所示的修改後的遷移器模板類。保存修改後的遷移器模板類,編譯遷移器模板類得到遷移器模板類的字節碼文件。
[0034]步驟29 )中,根據遷移器模板類類生成更新所需要的遷移器類,將遷移器類傳入虛擬機的具體步驟是:
291)遷移器模板類和更新的類重名,不能直接將遷移器模板類加載到運行時刻進行更新,對於多個模板類,會將其合併成一個遷移器類。
[0035]292)將合併後的遷移器類所在的位置信息通過消息發送到虛擬機,虛擬機端接收遷移器類,完成更新的準備工作。
[0036]步驟3)調試器請求虛擬機完成代碼更新,繼續調試的具體步驟是:
31)調試器在更新準備工作完成以後,通過調用JVMTI中的RedefineClasses接口用修改後的類替換原始的類,具體的執行過程是首先在堆中找到舊類,找到後懸掛正在執行的程序,通知類加載器加載新類的修改後的版本,通過調用遷移類中對應的遷移方法來實現對類實例的更新。
[0037]32)接著通過調用JVMTI提供的PopFrame接口使JVM重新執行被修改的方法,恢復現場,這樣一個完整的更新過程完成,調試器會等待軟體開發者的下一個調試命令。
[0038]下面給出本發明的一個具體實施例:
本發明是對Java語言調試的支持,Java程序以及調試器需要運行在Javelus虛擬機上。
[0039]軟體開發者在一個運行在Javelus虛擬機上的調試器裡調試Java代碼,一般所涉及到的調試命令是設置斷點、單步執行、條件執行、查看指定變量,查看堆棧信息等。當軟體開發者在調試到某一步時發現錯誤根源,這時候如果對代碼進行修改然後保存,調試器通過監聽調試器代碼修改的事件,會觸發對代碼修改事件的響應。
[0040]接下來就是代碼更新準備的階段,首先獲取修改前的類文件以及修改後的類文件存放於臨時文件夾中,然後將舊類和新類編譯為字節碼文件,通過比較新舊字節碼文件的不同獲得更新信息。
[0041]根據比較字節碼文件得到的更新信息來判斷是否需要遷移器來完成更新,如果需要遷移器,則生成一個遷移器模板類來幫助軟體開發者寫遷移器,軟體開發者需要修改遷移器模板類後,編譯遷移器模板類。然後通知調試器完成對遷移器模板類的修改以及編譯,接著將根據遷移器模板類合併生成遷移器類,將遷移器類傳入虛擬機完成更新的準備工作。
[0042]最後,調試器在更新準備工作完成以後,通過調用JVMTI中的RedefineClasses接口用修改後的類替換原始的類,對該類的實例更新則通過調用遷移類中對應的遷移方法來實現對象的更新。接著通過調用JVMTI提供的PopFrame接口使JVM重新執行被修改過的方法,恢復現場,這樣一個完整的更新過程完成,調試器會等待軟體開發者的下一個調試命令,可以繼續修改代碼並更新代碼。
[0043]上面結合附圖對本發明的實施方式作了詳細說明,但是本發明並不限於上述實施方式,在本領域普通技術人員所具備的知識範圍內,還可以在不脫離本發明宗旨的前提下做出各種變化。以上所述,僅是本發明的較佳實施例而已,並非對本發明作任何形式上的限制,雖然本發明已以較佳實施例揭露如上,然而並非用以限定本發明,任何熟悉本專業的技術人員,在不脫離本發明技術方案範圍內,當可利用上述揭示的技術內容做出些許更動或修飾為等同變化的等效實施例,但凡是未脫離本發明技術方案內容,依據本發明的技術實質,在本發明的精神和原則之內,對以上實施例所作的任何簡單的修改、等同替換與改進等,均仍屬於本發明技術方案的保護範圍之內。應當注意,為了使本發明更容易理解,上述的描述省略了對於本領域的技術人員來說是公知的、並且對於本發明的實現可能是必須的一些技術細節。
【權利要求】
1.一種調試時代碼動態更新方法,其特徵在於,包括以下步驟: 步驟一、軟體開發者使用調試器調試代碼; 步驟二、軟體開發者在調試時更改代碼並保存,觸發準備更新過程,包括代碼檢測,生成遷移器模板類,完成對遷移器模板類的修改,將更新信息傳入虛擬機中; 步驟三、調試器請求虛擬機完成代碼更新。
2.根據權利要求1所述的一種調試時代碼動態更新方法,其特徵在於,步驟二中所述準備更新過程的具體步驟是: 21)軟體開發者使用調試器對程序進行調試,通過設斷點進行單步調試; 22)調試器監聽調試時代碼發生改變的事件,當代碼發生改變時,響應代碼改變的事件,再通過檢測獲取當前調試代碼類文件所在位置,獲取更改代碼之後的類文件以及更改之前的類文件,將新舊代碼類文件存放到臨時文夾中; 23)編譯存放於臨時文件夾中的新舊代碼類文件,得到對應新舊代碼類文件的字節碼文件; 24)通過比較新舊代碼的字節碼文件得到更新說明文件,進而得到更新類型信息; 25)判斷是否需要遷移器來完成代碼更新, 當不需要時轉入步驟26),否則轉入27); 26)判斷代碼更新不需要遷移器,完成代碼更新過程; 27)判斷代碼更新需要遷移器,生成一個遷移器模板; 28)軟體開發者修改遷移器模板類中的代碼並保存,編譯修改後的遷移器模板類; 29)通知調試器完成對遷移器模板類的修改,更新根據遷移器模板類生成的遷移器類,將遷移器類傳入虛擬機。
3.根據權利要求2所述的一種調試時代碼動態更新方法,其特徵在於,步驟24)中,所述新舊版本字節碼文件的比較包括:方法體的變化、類的方法增加或刪除、類域的增加或刪除、類結構的變化。
4.根據權利要求2所述的一種調試時代碼動態更新方法,其特徵在於,步驟27)中,所述遷移器模板包括下述組成部分: 401、定義的域,一個模板類重定義了新類的所有域,使得在模板的方法中可以自由訪問要遷移的對象的各個域; 402、對象遷移方法,為實例方法,用以訪問舊類對象的域; 403、類遷移方法,為靜態方法,用以在更新後對類的第一次訪問中被調用,實現更新靜態域; 404、父類,當所述父類發生更新時,模板類將聲明該父類。
5.根據權利要求2所述的一種調試時代碼動態更新方法,其特徵在於:所述步驟28)中,軟體開發者根據前後代碼的不同來修改遷移器的模板類文件,保存修改後的遷移器模板類,編譯遷移器模板類得到遷移器模板類的字節碼文件。
6.根據權利要求2所述的一種調試時代碼動態更新方法,其特徵在於,所述步驟29)的具體步驟包括: 29-1)通過遷移器模板類生成遷移器類,將多個模板類合併成一個遷移器類; 29-2)將合併後的遷移器類所在的位置信息通過消息發送到虛擬機,虛擬機端接收遷移器類,完成更新的準備工作。
7.根據權利要求1所述的一種調試時代碼動態更新方法,其特徵在於,所述步驟三的具體步驟包括: 31)調試器在更新準備工作完成後,調用JVMTI中的RedefineClasses接口用修改後的類替換原始的類,首先在堆中找到舊類,找到後懸掛正在執行的程序,通知類加載器加載新類的修改後的版本,通過調用遷移類中對應的遷移方法來實現對該類實例的更新; 32)通過調用JVMTI提供的PopFrame接口使JVM重新執行被修改的方法,恢復現場。
8.根據權利要求1所述的一種調試時代碼動態更新方法,其特徵在於,所述調試器的調試代碼為Java代碼。
9.根據權利要求2所述的一種調試時代碼動態更新方法,其特徵在於,步驟21)中,所述單步調試的調試命令包括設斷點、單步執行、條件執行、監視對象或者監視堆棧。
10.根據權利要求1或2所述的一種調試時代碼動態更新方法,其特徵在於:所述虛擬機為 Javelus。
【文檔編號】G06F9/445GK104391717SQ201410656737
【公開日】2015年3月4日 申請日期:2014年11月18日 優先權日:2014年11月18日
【發明者】張同寶, 顧天曉, 馬曉星 申請人:南京大學