2013-11-26 67 views
0

我正在使用asm(這裏是文檔http://asm.ow2.org/asm40/javadoc/user/),更具體地說,我正在嘗試動態測試某些代碼。 我的問題是,我不知道如何以及如果我能夠通過什麼提供asm來讀取儀表代碼的實際變量。 即我能夠檢索我在計量代碼中計算的相應商店的LocalVariableNode,此時我想知道我存儲的值(不僅僅是可以輕鬆地使用LocalVariableNode類中提供的方法獲取的類型但實際值(如果它是一個布爾值,我想得到真或假))。 類似地,當加載字節碼指令發生時獲取該值將會很有趣。Java ASM如何讀取LOAD或STORE字節碼的值

希望我已經足夠具體,我檢查了是否有類似的東西已經被問到,但似乎沒有。

在此先感謝。 Nicolas

回答

0

我之前做過類似的事情,忘記了細節,但我想我可以給你一些指示。

當然,就像creichen在他的回答中所說的那樣,不可能得到與LocalVariable相關的確切值,但是可以對字節碼的整個抽象語法樹進行排序,並且知道可能的值是什麼類型在程序的某個位置分配給LocalVariable。

對於每個LocalVariableNode都分配了一個索引,因此在字節碼中,該值與LocalVariable不是靜態關聯的,因爲Java允許在該變量上可變。因此,爲了在程序的某個位置知道與LocalVariable相關的值,您必須基本模擬字節碼(JVM)的堆棧執行,然後有一個表來跟蹤每個LocalVariable的值賦值。棧的執行是通過模擬指令(操作碼),基本上是字節碼。然後逐漸建立一個Tree結構來存儲抽象語法樹。

我有一個代碼,但很醜陋,你可以去看看:https://github.com/davidlau325/BytecodeASTGenerator

+0

非常感謝,然後嘗試構建本地堆棧。 – Nicolas

0

你所要求的一般是不可能的。一個布爾存儲(astore,bastore,putfield,putstatic)彈出棧頂值並將其存儲在指定的位置。但是,這個棧頂值可以是任意計算的結果。例如:

boolean b = MyClass.decideWhetherProgramPHalts(); 

所以你要看的方法調用可能甚至可能不會終止。你的字節碼可能是這個樣子(只是從內存中簡述):

invokestatic "MyClass.decideWhetherProgramPHalts()Z" 
istore 1 

這樣被存儲的值從以前invokestatic進來,這可以從一個簡單的return true什麼網絡調用的一些嘗試解決我們知道的不可判定的問題。

如果你需要分析,它可以告訴你truefalseI-do-not-know,你可以嘗試靜態分析框架,如WALA(http://wala.sourceforge.net)。但請注意,大部分時間你會得到I-do-not-know。以下是你可能要考慮的主要技術:

  1. 數據流分析
  2. 抽象解釋

請注意,您可以自己砍了一個簡單的數據流分析,通過訪問指令在你的MethodNode中,但你的召回會比使用現有的工具要差(除非你在這方面投入很多工作)。

+0

感謝你,是有道理的。 – Nicolas