轉(zhuǎn)載請(qǐng)說(shuō)明出處:IDEA&Eclipse中debugger調(diào)試常用技巧
改變變量的值
在調(diào)試的過(guò)程中可以改變非final變量的值关串。
條件斷點(diǎn)
有時(shí)候斷點(diǎn)會(huì)打在循環(huán)里惧浴,或者希望在某個(gè)條件下才觸發(fā)斷點(diǎn)现使,這個(gè)時(shí)候條件斷點(diǎn)就派上用場(chǎng)了瞪慧,在idea里對(duì)著斷點(diǎn)右鍵。
如下,在循環(huán)里,希望i
的值為8的時(shí)候才開(kāi)始調(diào)試。
需要注意的是條件斷點(diǎn)可能會(huì)導(dǎo)致debug啟動(dòng)的時(shí)候非常慢(甚至僵死)祟剔,筆者試過(guò)在ThreadLocal#get里面使用條件斷點(diǎn),導(dǎo)致spring-mvc項(xiàng)目debug啟動(dòng)半小時(shí)都沒(méi)啟動(dòng)成功摩梧,最好啟動(dòng)后再啟用條件斷點(diǎn)物延。
代碼片段&&變量視圖
有時(shí)候你調(diào)試的時(shí)候,突然想增加一段代碼仅父,又不想重新啟動(dòng)調(diào)試叛薯,這個(gè)功能可以用上。
在調(diào)試的過(guò)程中同時(shí)改變了變量的視圖笙纤,用
toString
來(lái)顯示耗溜,可以看到list
里的兩個(gè)值1
和2
。
Evaluate or Inspect
上面的代碼片段使用到的是Evaluate
功能省容,這個(gè)功能很強(qiáng)大抖拴,比如我在跟蹤spring
源碼的時(shí)候,我想知道AOP
代理對(duì)象如何產(chǎn)生的時(shí)候腥椒,遇到如下代碼:
因?yàn)槲抑饕P(guān)注代理對(duì)象什么時(shí)候產(chǎn)生阿宅,所以這個(gè)時(shí)候我只想看看那個(gè)方法給我返回了代理對(duì)象,這時(shí)候我應(yīng)該直接
Step Over
還是Step Into
到resolveName
這個(gè)方法里呢笼蛛?可以用Evaluate
來(lái)幫忙:從上圖可以看出洒放,我評(píng)估了一下這個(gè)方法,發(fā)現(xiàn)這個(gè)方法能返回代理對(duì)象伐弹,顯然我需要
Step Into
到這個(gè)方法里拉馋。
Eclipse
如果想在Eclipse里執(zhí)行evalution或者叫Inspect,有兩種方式:
- 需要在window -> show view -> display打開(kāi)display面板惨好,然后在面板里執(zhí)行(
ctrl+u
)java語(yǔ)句。
image.png
image.png -
選中語(yǔ)句随闺,右鍵 -> Inspect(快捷鍵是Ctrl+Shift+I):
image.png
丟棄棧幀(Drop Frame)
大家應(yīng)該都遇到過(guò)調(diào)試代碼的時(shí)候想回到上一步日川,或者回到上一個(gè)調(diào)用方法的時(shí)候吧?IDE 為我們提供了一個(gè)Drop Frame的功能矩乐,可以讓我們丟棄當(dāng)前的棧幀龄句,如果不知道這個(gè)功能回论,你可能只能選擇重新啟動(dòng)debugger開(kāi)始調(diào)試,這樣效率有點(diǎn)低分歇。
假設(shè)有這樣的調(diào)用關(guān)系:methodA
-> methodB
-> methodC
-> methodD
如下:
代碼調(diào)試到第51行沛厨,想看看從50進(jìn)入到methodD
內(nèi)部調(diào)試捌肴,這個(gè)時(shí)候就可以使用丟棄棧幀了。在底下調(diào)用棧中右鍵methodC
-> Drop Frame
,就會(huì)回到methodB
調(diào)用的那一個(gè)棧幀企垦。
智能步入(Smart Step Into)/步入選擇(Step Into Selection)
有時(shí)候調(diào)試代碼的時(shí)候會(huì)存在層層嵌套的情況,這個(gè)時(shí)候step into可能就沒(méi)這么好用了艺谆,選擇性的step into就顯得很重要了弊决。
IDEA
Eclipse
Eclipse需要先選中想要Step Into的方法,然后按Ctrl+F5
進(jìn)入擅威,如下:
變量斷點(diǎn)
變量斷點(diǎn)在變量初始化或者變量值改變的時(shí)候可以是程序停在變量值改變的那行代碼上壕探。
當(dāng)然,變量斷點(diǎn)也是可以設(shè)置
condition
的郊丛,如上圖李请。
方法斷點(diǎn)&&Force step into
方法上也是可以打斷點(diǎn)的,比如有時(shí)候我們想進(jìn)入到j(luò)dk內(nèi)部的方法里厉熟,因?yàn)閖dk的class在編譯的時(shí)候?yàn)榱斯?jié)省空間捻艳,去掉了調(diào)試信息,用普通的step into
可能進(jìn)入不了方法內(nèi)部庆猫,這個(gè)時(shí)候可以在相應(yīng)的方法上打個(gè)斷點(diǎn)认轨,或者使用Force step into
進(jìn)入到方法體內(nèi)部。
多線(xiàn)程調(diào)試
idea中讓其他線(xiàn)程也在斷點(diǎn)中停下來(lái)月培。
通過(guò)Debugger窗口下拉菜單來(lái)切換線(xiàn)程:
eclipse中讓整個(gè)虛擬機(jī)都掛起嘁字,避免其他線(xiàn)程繼續(xù)執(zhí)行。
日志斷點(diǎn)(添加執(zhí)行語(yǔ)句)
有這樣一些場(chǎng)景:需要?jiǎng)討B(tài)插入一條執(zhí)行語(yǔ)句杉畜,或者調(diào)試的時(shí)候需要額外打印一些日志信息來(lái)協(xié)助觀察問(wèn)題纪蜒。有時(shí)候可能會(huì)選擇在代碼里寫(xiě)入一些語(yǔ)句,這樣會(huì)污染代碼而且可能忘記刪除或者注釋掉此叠,而且通過(guò)添加代碼的方式可能會(huì)導(dǎo)致整個(gè)項(xiàng)目重新編譯纯续,需要較長(zhǎng)時(shí)間。
紅框部分相當(dāng)于Log#info出來(lái)的信息灭袁。
當(dāng)然你也可以log出堆棧信息猬错,如下,勾選:
甚至你可以添加語(yǔ)句茸歧,然后讓debug的時(shí)候跳過(guò)這個(gè)斷點(diǎn)倦炒,不要停留,這樣你debug的時(shí)候斷點(diǎn)到這里就不會(huì)掛起:
強(qiáng)制返回(Force Return)
之前在windows上調(diào)試hadoop代碼的時(shí)候软瞎,有一段代碼要判斷可讀權(quán)限(boolean canRead()
)逢唤,總是返回false
導(dǎo)致程序異常而執(zhí)行中斷拉讯,然后發(fā)現(xiàn)可以在進(jìn)入某個(gè)方法后強(qiáng)制返回,強(qiáng)制返回一個(gè)true
就不會(huì)出錯(cuò)了鳖藕。
只要在對(duì)應(yīng)的方法上執(zhí)行:
右鍵
-> Force Return
就可以編寫(xiě)返回語(yǔ)句了魔慷。可以編寫(xiě)負(fù)責(zé)語(yǔ)句著恩,也可以調(diào)用方法院尔。本文的錄屏軟件使用的是ScreenToGif.exe。