同事改Bug飛快,原來掌握了這些代碼Debug技巧
引言
代碼Debug調試是研發工程師日常工作中必不可少的重要組成部分。進行代碼Debug調試的目的無非就兩個,一個是自我檢查代碼邏輯是否有問題,便于自己將Bug消滅在測試介入之前;另一個是進行線上問題排查定位,找到實際在跑業務的過程中出現的Bug。但是無論是哪個目的,高效率的進行代碼Debug調試必定會提高我們碼代碼的效率以及定位問題解決問題的效率,從而實現代碼白盒化自我觀測。本文主要羅列了10個常用的Debug技巧,可以讓我們定位代碼問題事半功倍。
Debug調試場景
回到上一步
進行代碼調試的過程中,有的時候由于自己點擊下一步的速度比較快,可能之前打的斷點命中后直接跳過去了進入到某個方法的內部,但是我們還是想看回頭看之前斷點中的情況,那么此時可以使用這個回到上一步功能即Drop Frame,快速定位到之前的代碼運行位置。我們都知道JVM通過棧幀保存方法調用地址的,因此實際上這部分的功能可以理解為舍棄當前的調用棧回到原來的調用處。
字段斷點
當我們需要知道類中某個屬性值到底什么時候被修改的時候,如果要從最起始的地方進行調試實在太過麻煩,因為有的時候我們可能并不知道屬性賦值的起始點到底在哪里,特別是在閱讀框架源碼的時候。那么此時可以嘗試在類的字段進行斷點,勾選上在屬性訪問或者屬性修改的時候將運行到屬性修改發生的地方或者屬性被訪問的地方,這樣可以大大提高我們找到屬性修改再沈地方被修改的效率。
Stream調試
Lambda表達式是JDK1.8的新特性,在實際的項目編碼也會被經常使用到來簡化一些循環操作的代碼。但是Lambda表達式并不好進行調試,因此不太方便查看stream流內部的值運行情況,此時我們需要借助于Java Stream Debuger這個插件,這樣我們在進行stream流debug的時候就可以看到內部各個值執行的流程以及最終結果,方便我們進行問題定位。
表達式結果查看
在進行Debug的過程中,在代碼的右側一般會默認展示一些變量當前的值,但是對于一些表達式的值并不會默認展示,而我們有的時候需要關注一下表達式在計算過程中的數據是否正確。此時便可以通過鼠標選中需要計算的代碼表達式然后結合(Alt+F8)快捷鍵查看表達式的計算結果。
debug篩選條件
在一些循環條件中,比如某個List中有100個String對象,但是我們在調試的時候希望快速找到滿足條件的對象,而不是在不關注的對象上面浪費時間進行debug,這個時候我們就可以使用debug篩選條件快速過濾出我們需要的對象,大大提升我們debug的效率。
異常斷點
進行斷點調試的時候,除了閱讀框架源碼理解技術原理或者熟悉新業務,大部分情況進行斷點調試都是出現了異常需要進一步定位具體原因。但是一般情況下當發生異常的時候,拋出來的異常要么被框架捕捉了,進入框架的源碼當中,要么被自己業務代碼中的try catch捕捉了,影響問題定位。因此我們想要當異常發生的時候可以停在拋異常的地方,方便我們進行問題定位。
1、在任意斷點處點擊鼠標右鍵進行更多debug設置,找到Java Exception Breakpoints添加自帶的Exception類型或者自定義的業務異常。
2、此時進入debug模式運行代碼,當代碼邏輯產生之前添加的異常類型后,代碼會停留在發生異常的地方,這樣異常調試就更加方便了。
遠程調試
在實際的項目開發中,經常會遇到本地調試沒毛病,但是部署到預發布環境或者生產環境中就會出現Bug的問題,這個時候我們只能通過遠程調試來具體定位問題到底是什么。
1、在debug模式配置中選擇Remote模式
2、配置遠程環境
服務以Jar形式運行
在服務啟動的時候需要增加啟動參數
java -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005 -jar business.jar
服務在Tomcat容器中
tomcat 的bin目錄下的catalina.sh文件中增加配置
JAVA_OPTS='-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005'
服務在Docker容器中
需要在dockerfile配置ENTRYPOINT,也就是服務的啟動參數。
注意:
遠程調試需要確保本地代碼合遠程代碼的完全一致,否則代碼行數匹配不上無法達到調試的效果。
強制返回
我們進行debug問題排查,有的時候只是想確認業務邏輯有沒有問題,并不想真正去執行一些耗費資源、或者改變數據的操作,那么在這種場景下,我們可以借助于強制返回的功能,不執行方法后面的代碼而指定一個返回值來繼續后續的業務邏輯debug。
從運行結果可以看得出來,加法的代碼邏輯實際并沒有執行,而是通過強制返回后直接執行了后面的業務邏輯。
運行時修改變量
在debug的過程中,有時候我們需要按照我們預想的邏輯進行問題排查定位,這種場景下我們可能需要修改某些變量的值以便于代碼走入不同的預想的業務邏輯。通過Alt + F8快捷鍵修改獲取指定變量的值,右鍵Set Value設置新的值。
輸入新的變量值后進行回車設置,如此變量值被改變了,原先的業務邏輯發在條件發生改變之后也發生了改變。
多線程調試
Idea默認的Debug模式下會阻塞所有的線程,只有當當前的調試線程邏輯走完之后才會進入其他的線程。那如果想要調試多線程場景下的業務邏輯應該怎么辦呢? 實際上在設置斷點的時候,鼠標右擊斷點,我們可以選擇Thread調試模式。
這樣我們在Debugger中就可以通過切換不同的線程來進行業務邏輯調試。
重用快捷鍵
1、F8:Step Over 程序執行到下一步
2、F7:Step Into 進入方法內部
3、 Alt+Shift+F7:強制進入方法內部,主要針對F7無法進入的方法內部的情況
4、Shift+F8:進入方法之后,不希望再一步步執行剩下的代碼,可以通過此快捷鍵跳出
5、Alt+F10:如果當前鼠標光標不在代碼運行處,通過此快捷鍵可以將光標回歸到代碼運行處
6、Alt+F9:鼠標光標在何處,可以直接通過此快捷鍵跳轉運行到光標處,無需斷點
7、Alt+F8:計算表達式的值,用鼠標選擇需要計算的表達式之后,通過此快捷鍵可以計算表達式的值
8、Ctrl+F5:比如改了某些代碼需要重新運行程序,可以使用此快捷鍵
9、F9:如果一段代碼中打了兩個斷點,當debug到第一個斷點后,按F9后代碼運行到第二個斷點處,如果再按F9則執行完所有的代碼,也就是說如果當前斷點后還有斷點則可以通過F9跳轉,如果沒有則執行完代碼邏輯。
10、Ctrl+Shift+F8:查看所有的當前所有的斷點