Eclipse的Debug除錯技巧大全
相關文章
一、Debug檢視
除錯中最常用的視窗是:
視窗 說明 Debug視窗 主要顯示當前執行緒方法呼叫棧, 以及程式碼行數(有除錯資訊的程式碼) 斷點Breakpoints視窗 => 斷點列表視窗,可以方便增加斷點,設定斷點條件,刪除斷點等 變數Variables視窗 => 顯示當前方法的本地變數,非static方法,包含this應用,可以修改變數值 程式碼編輯視窗 => 這個不用多說了 輸出Console視窗 => 日誌等輸出內容,除錯時,可以將關注的元件級別設定低一點,以便獲得跟多輸出資訊
另外輔助的視窗有:
視窗 說明 表示式expression視窗 => 寫上自己需要觀察的資料的表示式,或者修改變數值 Display視窗 => 可以在display中執行程式碼塊,輸出內容等 大綱Outline視窗 => 檢視當前類的方法,變數等 型別層級Type hierarchy視窗 => 檢視當前所在類的繼承層次,包括實現介面,類繼承層次 方法呼叫關係Call hierarchy視窗 => 檢視當前方法被哪些方法呼叫,呼叫方法在哪些類中、第幾行,可以直接開啟對應的方法 搜尋結果Search視窗 => 結合快捷鍵可以檢視變數、方法等在工作空間、專案、工作集中被引用或定義的程式碼位置
1)視窗全覽:
2)Debug View(執行緒堆疊檢視):
debug檢視允許您在工作臺上管理正在除錯和執行的程式,他顯示了你正在除錯的程式中掛起的執行緒的堆疊幀,程式中的每個執行緒作為樹的節點出現。他展示了正在執行的每個目標的程序。如果執行緒被掛起,它的堆疊幀以子元素的形式展示。以下是一些常用的debug按鈕:
1.表示當前實現繼續執行直到下一個斷點,快捷鍵為F8。
2.表示打斷整個程序
3.表示進入當前方法,快捷鍵為F5。
4.表示執行下一行程式碼,快捷鍵為F6。
5.表示退出當前方法,返回到呼叫層,快捷鍵為F7。
6.表示當前執行緒的堆疊,從中可以看出在執行哪些程式碼,並且整個呼叫過程,以及程式碼行號
詳細介紹:
Skip All Breakpoints : 將所有斷點設定為被跳過的,設定了Skip All Breakpoints之後,所有斷點上都會有一個斜線,表示斷點將被跳過,執行緒不會在該斷點處被掛起。
Drop to Frame : 這個命令可以讓程式回到當前方法的開頭第一行重新開始執行,可以重新執行這個java堆疊幀,可以選擇一個指定的堆疊幀,然後點選 Drop to Frame,這樣就可以重新進入指定的堆疊幀。使用Drop to Frame時候需要注意:
1.不能drop到已經執行過的方法棧中的方法中。
2.drop到stack frame中時,不會改變全域性資料原有的值,比如,一個包含元素的vertor並不會被清空。
Step Filters : 這個功能比較簡單,就是當我們在debug的時候想要忽略一些我們不關注的類時,可以開啟Step Filters進行過濾,程式會一直執行直到遇到未經過濾的位置或斷點。Step Filters功能由Use Step Filters,Edit Step Filters,Filter Type,Filter Package四項組成。具體操作如下:
步驟 1: Windows -> Preferences -> Java -> Debug -> Step Filtering.
步驟 2:選擇‘Use Step Filters’
步驟 3:在螢幕上選中所需的選項。你可以新增你自己程式碼庫中的部分程式碼。
步驟 4:點選‘Apply’
原理上,Edit Step Filter命令用於配置Step Filter規則,而Filter Type與Filter Package分別指的是過濾的Java型別與Java Package。
Step Return : 跳出當前方法,在被呼叫方法的執行過程中,使用Step Return會在執行完當前方法的全部程式碼後跳出該方法返回到呼叫該方法的方法中。
Step Over : 在單步執行時,在函式內遇到子函式時不會進入子函式內單步執行,而是將子函式整個執行完在停止,也就是把子函式整個作為一步。
Step Into:單步執行,遇到子函式就進入並且繼續單步執行
Resume:恢復暫停的執行緒,直接從當前位置跳到下一個斷點位置。
Suspend:暫停選定的執行緒,這個時候可以進行瀏覽或者修改程式碼,檢查資料等。
Eclipse通過Suspend與Resume來支援執行緒的暫掛與恢復。一般來講,Suspend適用於多執行緒程式的除錯,當需要檢視某一個執行緒的堆疊幀及變數值時,我們可以通過Suspend命令將該執行緒暫掛。Resume用於恢復。
有兩種Resume需要注意:
第一是當在除錯過程中修改程式程式碼,然後儲存,點選Resume,此時程式會暫掛於斷點。
第二是當程式丟擲異常時,執行Resume,程式也會暫掛於斷點。
Terminate : Eclipse通過Terminate命令終止對本地程式的除錯。
Disconnect:Eclipse使用Disconnect命令來終止與遠端JVM的socket連線。
1、除錯執行
標記 功能 快捷鍵 描述 6.4 Step Info F5 -> 單步進入(如果有方法呼叫,將進入呼叫方法中進行除錯); 6.4 Step Over F6 -> 單步跳過(不進入行的任何方法呼叫中,直接執行完當前程式碼行,並跳到下一行); 6.4 Step Return F7 -> 單步返回(執行完當前方法,並從呼叫棧中彈出當前方法,返回當前方法被呼叫處); 6.5 Resume F8 -> 恢復正常執行(直到遇到下一個斷點); 7.4 Run to Line Ctrl+R -> 執行到當前行(將忽略中間所有斷點,執行到當前游標所在行); 6.3 Drop To Frame 無 -> 回退到指定方法開始處執行,這個功能相當贊。 在方法呼叫棧上的某個方法右鍵,選擇Drop To Frame就可以從該方法的開始處執行 比如重新執行本方法,可以在本方法上用Drop To Frame,將從本方法的第一行重新執行。 當然對於有副作用的方法,比如資料庫操作,更改傳入引數的物件內容等操作可能重新執行就再是你想要的內容了。 6.1+6.2 Copy Stack 無 -> 拷貝當前執行緒棧資訊
如果在除錯時,需要排除一些類、包等不需要進入除錯,可以使用Edit Step Filters設定。
A6的properties: Java程序啟動相關資訊,包括控制檯啟動引數,環境引數等。如果引數啟動引數有問題可以先看看這裡的實際啟動引數是不是有誤。另外還可以檢視虛擬機器支援除錯的相關選項。
2、資料檢視
標記 功能 快捷鍵 描述 7.4 Inspect ctrl+shift+i -> 察看選擇的變數、表示式的值或執行結果, 再次按ctrl+shift+i可以將當前表示式或值新增到Expressions視窗中檢視; 7.4 Display ctrl+shift+d -> 顯示選擇的變數、表示式的值或執行結果, 再次按ctrl+shift+d可以將當前表示式或值新增到Display視窗中顯示; 7.4 Execute ctrl+u -> 執行選擇表示式; 7.4 Run to Line ctrl+r -> 執行到當前行(將忽略中間所有斷點,執行到當前游標所在行); 7.3 All Instances ctrl+shift+n -> 檢視選擇的類的所有物件,這個功能超讚; 7.3 Instance Count 無 -> 檢視選擇的類的所有物件個數; 7.4 Watch 無 -> 添加當前變數、表示式到Expressions視窗中;
3)Variables View (變數檢視)
1.為變數名檢視,顯示當前程式碼行中所有可以訪問的例項變數和區域性變數
2.顯示所有的變數值
3.可以通過該視窗來改變變數值
Variables View顯示與Debug View中選定的堆疊幀相關的變數資訊,除錯Java程式時,變數可以選擇將更詳細的資訊顯示在詳細資訊窗格中。此外,Java物件還可以顯示出其包含的屬性的值。在該視窗中選中變數滑鼠右鍵點選可以進行許多操作,主要操作有以下這些:
All Instances:開啟一個對話方塊來顯示該java類的所有例項,使用該功能需要java虛擬機器支援例項的檢索。
All References::開啟一個對話方塊來顯示所有引用了該變數的java物件,
Change Value::更改變數的值,該功能可以和Drop to Frame聯合使用進行程式的除錯。使用這兩個功能就可以代替重新debug
Copy Variables:複製變數的值,尤其在變數值很長(比如json資料)的時候,這個功能就派上用場了。
Find:有的時候一個類中變數特別多的時候,可以進行查詢。
4)Breakpoints View (斷點檢視)
1.顯示所有斷點
2. 將當前視窗1中選中的埠失效,再次點選啟用。
3.異常斷點
Breakpoints View將列出你在當前工作區間裡設定的所有斷點,雙擊斷點可以進入到程式中該斷點的位置。還可以啟用或禁用斷點,刪除,新增新的,根據工作組或點命中計數給他們分組。在使用斷點是有以下兩個技巧是十分有用的:
Hit Count: 是指定斷點處的程式碼段執行多少次,最典型的就是迴圈,如果要讓一個迴圈執行10次就執行緒掛起,則指定Hit Count值為10,那麼當前的迴圈執行到第九次的時候就會掛掉。
Conditional:顧名思義,就是條件判斷,例如我們需要迴圈變數i==10時,執行緒掛起,則條件設定為i==10,選擇Suspend when “true”。
那如果上面的Hit Count和Conditional都選擇的話,如果表示式和值設定不合理則會失效。如果選擇Suspend when value changes,那麼可能在Conditional在變數值發生改變的時候就掛起。
5)Expressions View (表示式檢視)
1.表示式
2. 點選此可以新增一個表示式
要在 Debug 透檢視的編輯器中求表示式的值,選中設定有斷點的一整行,並在上下文選單中選擇 Inspect 選項。表示式是在當前堆疊幀的上下文中求值的,其結果顯示在 Display 視窗的 Expressions 檢視中。 比如我想要計算變數a+b的值,那麼就可以在表示式檢視中加一個表示式:a+b
6)Display View
可以使用這個檢視,輸入或者演算一些新的程式碼。這些程式碼在當前的除錯位置的上下文環境中被執行,這意味著,你可以使用所有變數甚至是內容助手。要執行你的程式碼的話,只需標記它,並使用右鍵選單或者CTRL+U(執行)或者 CTRL+SHIFT+I (檢查)
7)程式碼檢視輔助視窗
1、程式碼檢視:
程式碼檢視,用來顯示具體的程式碼。其中綠色部分是指當前將要執行的程式碼
標記 功能 快捷鍵 描述 11.1~11.5 quick type hierarchy ctrl+t 檢視當前類、介面的繼承層次, 預設進入時,顯示繼承/實現當前類/方法的子類,子介面11.1;再次ctrl+t,將顯示當前類、介面繼承/實現的超類/介面11.2;除錯時,經常用該功能,在介面或抽象類的方法呼叫處11.3,ctrl+t察看實現類11.4,直接導航到對應的實現方法中11.5。 quick outline ctrl+o 檢視當前類的大綱,包括方法,屬性等內容; 用處不大; open declarations F3 檢視變數、屬性、方法定義的地方
2、Call Hierarchy視窗:
標記 功能 快捷鍵 描述 12.1~12.2 open call hierarchy ctrl+alt+h 檢視方法被呼叫層次, 可以看當前方法被呼叫的地方12.1,或者當前方法呼叫了其他類的方法12.2
3、Type Hierarchy視窗:
標記 功能 快捷鍵 描述 13.1~13.4 open type hierarchy F4 檢視繼承層次, 可以檢視類的繼承層次,包括子類父類13.1, 或者類實現的介面繼承層次13.2,還會根據選擇的類/介面,在右邊顯示該類的大綱13.3、 13.4; 13.3可以選擇是否顯示父類/父介面的屬性、方法等
4、Search 視窗:
標記 功能 快捷鍵 描述 14.1 declarations ctrl+g 相同的方法簽名在工作空間中及第三方jar包中被定義的位置14.1 14.2 references ctrl+shif+g 當前選中的變數、屬性、方法在工作空間中及第三方jar包中被引用的位置14.2 14.3 ctrl+shift+u 檢視變數、屬性 、方法在當前類中出現的地方14.3 14.4 implements 檢視實現當前介面的類14.8 14.4~14.7 顯示方式 可以選擇不同的顯示方式,具體看圖
二、Debug
1.設定斷點
在原始碼檔案中,在想要設定斷點的程式碼行的前面的標記行處,雙擊滑鼠左鍵就可以設定斷點,在相同位置再次雙擊即可取消斷點。有的時候我們還有這樣的需要,就是我並不想一行一行的執行程式碼,比如一個for迴圈會迴圈1000多遍,我只想在第500遍的時候讓執行緒掛起進行除錯,這個時候我們可以使用條件斷點。 設定條件斷點:我們可以給該斷點設定觸發條件,一旦滿足某條件是才開始除錯,可以在斷點處點選滑鼠右鍵,選擇Breakpoint Properties進入斷點設定頁面,剛剛在講斷點檢視的時候我們學到過Hit Count和Conditional的用法,這裡可以設定條件和執行次數。
1.1)斷點型別及斷點視窗
在除錯中可以設定的斷點型別有五種:
1.行斷點(line breakpoints) : 條件斷點,顧名思義就是一個有一定條件的斷點,只有滿足了使用者設定的條件,程式碼才會在執行到斷點處時停止。
2.方法斷點(method breakpoints ): 方法斷點的特別之處在於它可以打在 JDK的原始碼裡,由於 JDK 在編譯時去掉了除錯資訊,所以普通斷點是不能打到裡面的,但是方法斷點卻可以,可以通過這種方法檢視方法的呼叫棧。
3.觀察斷點(watch breakpoints-成員變數訪問變更)
4.異常斷點(exception breakpoints)
5.類載入斷點(class load breakpoints)
每種斷點的設定有些許不一樣,可以在斷點上右鍵->Breakpoint properties進行設定,但一般在斷點視窗有快速設定的介面,Breakpoint properties中多了filter, 其實比較雞肋,用處不大。
斷點相關的快捷鍵:
快捷鍵 說明 ctrl+shift+b 在游標處大斷點/取消斷點 ctrl+alt+b 忽略所有斷點 Alt+shift+q, b 啟用斷點視窗
1、行斷點: 在方法中的某一行上打斷點1.1、1.4。行斷點可以設定掛起執行緒/VM的條件1.3,訪問次數1.2。 1.3中的條件是,spring在註冊Bean定義(registerBeanDefinition)時,如果是org.springframework.demo.MyBean,就掛起執行緒,可以開始單步除錯了。 對於命中次數(hit count)1.2的使用,一般是在迴圈中,第N個物件的處理有問題,設定hit count = N, 重除錯時,可以方便到達需要除錯的迴圈次數時,停下來除錯。
2、方法斷點:在方法上打斷點2.1、2.2。方法斷點的好處是可以從方法方法進入或者退出時2.3,停下來除錯,類似行斷點,而且只有行斷點和方法斷點有條件和訪問次數的設定功能。 但是方法斷點還有另外一個好處,如果程式碼編譯時,指定不攜帶除錯資訊,行斷點是不起作用的,只能打方法斷點。 有興趣的可以通過A1將Add line number… 前的勾去掉, 除錯下看看。
3、觀察斷點: 在成員變數上打的斷點3.1、3.3。只有物件成員變數有效果,靜態成員變數不起作用。 可以設定變數被訪問或者設定的時候掛起執行緒/VM 3.2,也就是類似3.4的所有對成員變數的訪問或者設定的方法都會被監控到
4、異常斷點: 異常斷點可以通過4.6新增,或者點選日誌資訊中輸出的異常類資訊新增。 異常斷點4.1,系統發生異常時,在被捕獲異常的丟擲位置處或者程式未捕獲的異常丟擲處4.2、4.4, 掛起執行緒/VM, 也可以指定是否包括異常的子類也被檢測4.3、4.5。
另外除了以上正常設定的異常掛起,從java->debug中可以設定掛起執行,主要有下面兩個:
1、是否在發生全域性未捕獲時掛起(suspend execution on uncaught exceptions),除錯時,老是有異常掛起影響除錯,但是沒有設定異常斷點的情況,就可以勾選掉這個選項;
2、是否在編譯錯誤時掛起,一般在邊除錯邊改程式碼時會發生這種情況;
另外要提一個的是有main方法啟動的應用,可以在除錯配置中勾選stop in main A3, 程式進入時,會掛起執行緒,等待除錯。
5、類載入斷點: 在類名上打的斷點5.1。介面上是打不了類載入斷點的,但是抽象類是可以的,只是在除錯的時候,斷點不會明顯進入classloader中,單步進入知會進入到子類的構造方法中,非抽象類在掛起執行緒後單步進入就會到classloader中(如果沒有filter過濾掉的話)5.3。類載入斷點不管是打在抽象或者非抽象類上,都會在類第一次載入或者第一個子類第一次被載入時,掛起執行緒/VM5.2。
2.除錯程式
1、除錯本地 Java 語言程式
在所有除錯中,除錯一個Java程式是最簡單的,主要有設定斷點、啟動除錯、單步執行、結束除錯幾步。
1)設定斷點:
2)啟動除錯:Eclipse提供四種方式來啟動程式(Launch)的除錯,分別是通過選單(Run –> Debug)、圖示(“綠色臭蟲”)、右鍵->Debug As以及快捷鍵(F11),在這一點上,與其他命令(例如Run)類似。
彈出提示,需要切換到除錯(Debug)工作區,勾選“Remember my decision”,記住選擇,則下次不再提示,然後點選【Yes】。
3)單步執行:主要使用前面講過的幾個檢視進行除錯,其中debug檢視中的幾個按鈕有快捷鍵:
Step Retuen(F7)
Step Over (F6)
Step Into (F5)
結束除錯:通過Terminate命令終止對本地程式的除錯。
二、案例
場景一:小明寫了一個任務執行者,該執行者不間斷的執行一些任務,在現網上運行了一段時間後,發現有概率的出現一些故障,發現執行一段時間後,該任務者異常退出了,退出的因為是空指標,可以小明想要在本地debug,不知道斷點打在哪裡,該問題是概率事件,不一定會出現,所以小明debug幾遍下來後,頭暈眼花,連程式碼都看不清楚了,小明想要是能有個斷點每當出現空指標異常的時候就停下來讓他發現問題,那該多好呀。
異常斷點
異常斷點:在定位問題的過程中,常常會遇到斷點無法打到合適的位置,以至於和問題的觸發點千差萬別,所以這個時候不妨試試異常斷點,顧名思義,異常斷點是指丟擲某種異常後自動掛起的斷點。
點選紅色部位,增加一個異常斷點
輸入想要定位的異常型別,例如NullPointerException,這樣系統中丟擲任何NullPointerException異常後,都會掛起當前執行緒,給你機會去定位問題。
場景二:小明寫了一個巨大的迴圈,在調測程式碼時,小明發現每當迴圈到第100000次的時候,就是出現問題,沒有達到自己的預期,於是小明在迴圈裡打了個斷點,想看看到底怎麼回事,可小明萬萬沒有想到,想要到達100000次迴圈是多麼的困難,小明這個時候已經開始浮想聯翩,如果能有這樣的斷點:
If 迴圈次數== 100000,執行緒停下來
條件斷點
如右圖,迴圈1000次,如果想要在迴圈到500次的時候停下來,可以建立一個條件斷點,右擊斷點懸著Breakpoint Properties。
選中Enable Condition
在空白處,新增你自己的條件,如果條件返回true,執行緒會被掛起,如果為false,則忽略該異常
Hit Count為該斷點經過多少次後,正式掛起執行緒,如果設定為500,則表達前499次,經過該斷點都不會停下,當第500次,該斷點會掛起當前執行緒。
表示式
表示式可以檢視一些在當前程式碼中沒有的命令列,方便定位問題。
場景三:小明最近遇到一個難題,在呼叫一個第三方外掛時總是會有問題,小明懷疑是第三方外掛的bug,但小明沒有找到原始碼不能進行debug,小明該怎麼辦呢?
Debug定位第三方外掛的問題
1.使用反編譯工具將程式碼反編譯
2.將反編譯後的原始碼進行過濾
3.修復原始碼編譯錯誤
4.進行debug
參考:
http://blog.csdn.net/u010075335/article/details/51222493