1. 程式人生 > >Eclipse除錯進階-結合Dubbo除錯例項分析

Eclipse除錯進階-結合Dubbo除錯例項分析

本文你會掌握的Eclipse進階技能:

● 除錯窗口裡預設顯示多執行緒
● 根據需要暫停某執行緒,然後在需要時候恢復
● 使用Expression執行程式碼直觀計算複雜的條件值
● Step Into(F5)
● Step Over (F6)
● Step Return (F7)
● Drop to Frame
● Use Step Filters

Dubbo Demo 除錯執行時候 Eclipse介面顯示:

這裡寫圖片描述

除錯注意:

1) 啟動測試用例DemoProvider時候,該程式在某些地方會啟動多執行緒(例如某些後臺監控heartbeat執行緒)。因此從入口開始啟動後不要以為程式是單執行緒執行的,特別是除錯程式時候如果習慣斷點打得多,要注意Eclipse介面停頓的地方究竟是你關心的主執行緒還是其它監控執行緒。

2) 可以根據需要暫停(Suspend)某些條監控執行緒,目的是方便針對關心的主執行緒觀察日誌,不至於在觀察主執行緒程式碼流程時候突然跳轉到某監控執行緒的程式碼片段。

暫停heartbeat執行緒
這裡寫圖片描述

3)右鍵選擇Watch監控開啟表示式介面,在Expressions視窗的Name裡可以填當前執行程式碼複雜的條件,例如( lastWrite != null && now - lastWrite > heartbeat ) 想直觀知道答案而非逐個變數心算結果
這裡寫圖片描述

這裡寫圖片描述

下面介紹的功能使用中如遇到手動breakpoints,則除錯跳轉以手動增加的breakpoint為優先順序處理。

● Step Into(F5)
● Step Over (F6)
● Step Return (F7)
● Drop to Frame
● Use Step Filters

4) 例如,下面程式碼當前執行在第一行,
第1行: for (Container container : containers) {
第2行: container.start();
第3行: logger.info(“Dubbo ” + container.getClass().getSimpleName() + ” started!”);
第4行: }

點選F6則按照順序執行到第2行。
此時,
操作:點選F5就會進入到container.start()的具體程式碼裡。
or
操作: 點選F6就執行到第3行。注意,如果container.start()方法裡存在手工新增breakpoint,則F6也會進入start()方法體裡。

5)假設按上面操作當前執行到start()方法體裡下面第3行。
class Container {
public void start() {
第1行: String configPath = ConfigUtils.getProperty(SPRING_CONFIG);
第2行: if (configPath == null || configPath.length() == 0) {
第3行: configPath = DEFAULT_SPRING_CONFIG;
第..行: … … … …
第..行: … … … …
第n行: }
}
}

接著,由於還有很多行要執行,此時不希望不停按F6,那麼可以直接點選F7執行完方法體裡剩下程式碼然後返回到4)中例子的第2行

6)假設按上面步驟執行到例子4)中第3行,這時候如果希望程式返回到第1行重新執行一次,可以在除錯的主視窗stack裡選擇for (Container container : containers) {這行然後點選Drop to Frame 即可。

7) Use Step Filters 用法就是不希望執行某個指定的程式碼。這個一般意義不大,但用得上時候又很方便。
場景如下:
windows -> preference -> Step Filtering 引入某個不希望除錯的class
這裡寫圖片描述

例如新增例子5)中的class Container,然後在除錯視窗點按下面小圖示。
這裡寫圖片描述

則程式執行至第2行時候,點選F5 Step into不會生效,會直接執行到第3行。
第1行: for (Container container : containers) {
第2行: container.start();
第3行: logger.info(“Dubbo ” + container.getClass().getSimpleName() + ” started!”);
第4行: }

這個Use Step Filters 大部分情況下意義不大是因為很多時候在class Container 的start 方法裡已存在手工新增的breakpoint,則無論按F5,F6程式都會跳轉到該breakpoint

但是,如果是下面的場景,使用Use Step Filters卻帶來某些方便。

例如某些複雜巢狀方法只有一行程式碼,這時候如果我只關心進入obj1.method的方法體而不進入obj2,obj3的method方法體。最直接方法就是新增obj2,obj3為 filters
然後執行到下面程式碼時候,F5 Step into就只會進入obj1的method,省去先進入obj3,obj2的過程。
obj1.method(obj2.method(obj3.method()))