亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

跟蹤類字節碼中方法實現的變化

跟蹤類字節碼中方法實現的變化

智慧大石 2023-04-13 10:32:32
我在一些 kotlin 代碼中有一些抽象項目(讓我們稱之為項目)字節碼(它是每個類的),每個類字節碼都存儲為 ByteArray;任務是告訴每個類中的哪些特定方法在項目的構建之間被修改。也就是說,同一個類的The Project有兩個ByteArray,但是屬于不同的版本,需要比較準確。一個簡單的例子。假設我們有一個簡單的類:class Rst {    fun getjson(): String {        abc("""ss""");        return "jsonValid"    }    public fun abc(s: String) {        println(s)    }}它的字節碼存儲在 oldByteCode 中?,F在類發生了一些變化:class Rst {        fun getjson(): String {            abc("""ss""");            return "someOtherValue"        }        public fun newMethod(s: String) {            println("it's not abc anymore!")        }    }它的字節碼存儲在 newByteCode 中。這是主要目標:將 oldByteCode 與 newByteCode 進行比較。這里我們有以下變化:getjson() 方法已更改;abc() 方法已被刪除;newMethod() 已創建。因此,如果方法的簽名保持不變,則該方法已更改。如果沒有,它已經是一些不同的方法了。現在回到實際問題。我必須通過字節碼了解每個方法的確切狀態。我現在擁有的是 jacoco 分析器,它將類字節碼解析為“包”。在這些包中,我有包、類、方法的層次結構,但只有它們的簽名,所以我無法判斷方法的主體是否有任何變化。我只能跟蹤簽名差異。是否有任何工具、庫可以將類字節碼拆分為其方法字節碼?例如,我可以用它們計算哈希值并進行比較。也許 asm 庫對此有任何處理?歡迎任何想法。
查看完整描述

1 回答

?
富國滬深

TA貢獻1790條經驗 獲得超9個贊

僅比較字節碼甚至哈希的方法不會產生可靠的解決方案,事實上,對于此類問題根本沒有合理的解決方案。

我不知道,其中有多少適用于 Kotlin 編譯器,Java 編譯器不需要生成相同的字節碼,即使使用相同的版本來編譯完全相同的源代碼。

即使我們假設 Kotlin 編譯器具有出色的確定性,甚至跨版本,它也不能忽視 JVM 的演變。例如,任何編譯器都不能忽略/指令的刪除,即使在嘗試保守時也是如此。jsrret但它很可能也會包含其他改進,即使不是被迫的1。

所以簡而言之,即使整個源代碼沒有改變,假設編譯后的形式必須保持不變也是不安全的。即使使用顯式確定性編譯器,我們也必須在使用更新版本重新編譯時為更改做好準備。

更糟糕的是,如果一種方法發生變化,它可能會對其他方法的編譯形式產生影響,因為只要需要常量或鏈接信息,指令就會引用常量池中的項目,并且這些索引可能會發生變化,具體取決于其他方法如何使用常量池。當訪問前 255 個池索引之一時,某些指令也有優化的形式,因此編號的更改可能需要更改指令的形式。這反過來可能對其他指令有影響,例如開關指令具有填充字節,具體取決于它們的字節代碼位置。

另一方面,如果新常量碰巧在池中與舊常量相同的位置結束,則僅在一個方法中使用的常量值的簡單更改可能根本不會影響方法的字節碼。

所以,要判斷兩個方法的代碼是否實際上相同,無法繞過指令解析并在一定程度上理解它們的含義。只比較字節或哈希是行不通的。

1 命名一些非強制性更改,類文字的編譯已更改,同樣,字符串連接從 using 更改StringBuffer為 useStringBuilder并再次更改為 useStringConcatFactory,getClass()內部null檢查的使用更改為requireNonNull(…),等等。不同語言的編譯器不會必須跟隨,但沒有人愿意被落在后面……

還有一些錯誤需要修復,比如過時的指令,沒有編譯器會為了保持確定性而保留這些錯誤。


查看完整回答
反對 回復 2023-04-13
  • 1 回答
  • 0 關注
  • 125 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號