2014-05-14 113 views
0
設置斷點

我試圖以編程方式運行JDB。與任何理智的調試器不同,JDB使用類名稱而不是源文件名引用源代碼。我假設它涉及具有存儲在多個.class文件,而不是單個文件字節碼(你所期望的編譯與-g標誌產生一些參考源文件,但讓事情容易是不是Java的方式.. 。)在內部和匿名類的方法,加多寶

當加多寶指的是類我通常可以做一些字符串操作,並期待在源文件名找出哪些源文件聲明相關的類。當我需要爲斷點提供一個類名時,我可以讀取該文件以獲取包名,使用文件名作爲類名並以此方式生成完整的類名。這兩種情況我讓他們工作。

的問題開始與內部類和匿名類。它們駐留在它們自己的類文件中,並且它們的名稱是包含它們的類的損壞版本。爲了在那裏設置一個斷點,我需要重名的名字。

例如 - 這是Main.java(+行號):

1: public class Main{ 
2: public static void main(String[] args){ 
3:  new Object(){ 
4:   @Override public String toString(){ 
5:    System.out.println("hi"); 
6:    return ""; 
7:   } 
8:  }.toString(); 
9: } 
10:} 

我把它用javac -g Main.java,並得到Main.classMain$1.class編譯。我運行jdb

Initializing jdb ... 
> stop on Main.main 
Deferring breakpoint Main.main. 
It will be set after the class is loaded. 
> run Main 
run Main 
Set uncaught java.lang.Throwable 
Set deferred uncaught java.lang.Throwable 
> 
VM Started: Set deferred breakpoint Main.main 

Breakpoint hit: "thread=main", Main.main(), line=3 bci=0 
3    new Object(){ 

(我需要的那部分加載Main.class - 否則,我只想得到「它將類加載後進行設置。」對於所有的斷點設置的嘗試。)

如果我設置8號線斷點它正常工作:

main[1] stop at Main:8 
Set breakpoint Main:8 

如果我設置行5斷點 - 這是匿名類的一部分 - 我得到一個錯誤:

main[1] stop at Main:5 
Unable to set breakpoint Main:5 : No code at line 5 in Main 

5號線明確包含的代碼 - 問題是,代碼不會被編譯到Main.class - 它編譯成Main$1.class,所以我需要,而不是寫:

main[1] stop at Main$1:5 
Deferring breakpoint Main$1:5. 
It will be set after the class is loaded. 

現在,Java的方式拆分字節碼轉換爲.class文件是確定的,在這個簡單的例子可以很容易地找出去的地方 - 當你與人眼審視它 - 但我需要一種以編程方式計算的錯位類名(與Vimscript中)對現實世界的源文件。試圖對源文件進行語法分析並找出哪個是太複雜的任務 - 應該是一個更簡單的方法。

也許從.class文件中提取信息,或質疑加多寶這件事,甚至使加多寶使用源文件名像任何理智的語言,任何理智的調試器...

回答

0

我有同樣的問題。作爲一個quickfix,我只是在所有Main $ [x] .class中爲類名(在你的情況下是Object)進行了grep。

如果您發現很多人,你必須使用它們出現在源文件中的順序的索引。