本篇內(nèi)容主要講解“IntelliJ IDEA遠(yuǎn)程調(diào)試的方法是什么”,感興趣的朋友不妨來看看。本文介紹的方法操作簡(jiǎn)單快捷,實(shí)用性強(qiáng)。下面就讓小編來帶大家學(xué)習(xí)“IntelliJ IDEA遠(yuǎn)程調(diào)試的方法是什么”吧!
創(chuàng)新互聯(lián)公司是一家專注于成都做網(wǎng)站、成都網(wǎng)站設(shè)計(jì)與策劃設(shè)計(jì),果洛州網(wǎng)站建設(shè)哪家好?創(chuàng)新互聯(lián)公司做網(wǎng)站,專注于網(wǎng)站建設(shè)十載,網(wǎng)設(shè)計(jì)領(lǐng)域的專業(yè)建站公司;建站業(yè)務(wù)涵蓋:果洛州等地區(qū)。果洛州做網(wǎng)站價(jià)格咨詢:18982081108
如果你是做 Java 開發(fā)的,相信你不會(huì)沒有聽過 IntelliJ IDEA ,和大多數(shù) Java 開發(fā)者一樣,我一開始的時(shí)候也是用 Eclipse 來進(jìn)行開發(fā),但是自從換了 IDEA 之后,就再也離不開它了,徹底變成了 IDEA 的忠實(shí)粉絲(不好意思,打一波廣告。。)。
不得不說,JetBrains 這家來自捷克的軟件公司真的是良心企業(yè),所出產(chǎn)品皆是精品,除了 IDEA,還有 WebStorm,PhpStorm,PyCharm 等,風(fēng)格都是很類似的,一些類似的快捷鍵包括調(diào)試技巧也是通用的。
打開 IDEA 的調(diào)試面板,如下圖所示,可以大致的將其分成五個(gè)部分:
單步跟蹤
斷點(diǎn)管理
求值表達(dá)式
堆棧和線程
變量觀察
說起調(diào)試,估計(jì)很多人第一反應(yīng)就是對(duì)程序進(jìn)行一步一步的跟蹤分析,其實(shí) IDEA 提供了很多快捷鍵來幫助我們跟蹤程序,大抵可以列出下面幾個(gè)技巧:
Show Execution Point
調(diào)試時(shí)往往需要瀏覽代碼,對(duì)代碼進(jìn)行分析,有時(shí)候在瀏覽若干個(gè)源文件之后就找不到當(dāng)前執(zhí)行到哪了,可能很多人會(huì)使用 Navigate Back 來返回,雖然也可以返回去,但可能需要點(diǎn)多次返回按鈕,相對(duì)來說使用這個(gè)技巧快速定位到當(dāng)前調(diào)試器正在執(zhí)行的代碼行要更簡(jiǎn)便。
Step Over
這是最基本的單步命令,每一次都是執(zhí)行一行代碼,如果該行代碼有方法會(huì)直接跳過,可以說真的是一步一個(gè)腳印。
Step In / Force Step In
Step Over 會(huì)跳過方法的執(zhí)行,可以觀察方法的返回值,但如果需要進(jìn)到方法里面,觀察方法的執(zhí)行細(xì)節(jié),則需要使用 Step In 命令了。另外,Step In 命令也會(huì)跳過 jdk 自帶的系統(tǒng)方法,如果要跟蹤系統(tǒng)方法的執(zhí)行細(xì)節(jié),需要使用 Force Step In 命令。
關(guān)于單步的時(shí)候忽略哪些系統(tǒng)方法,可以在 IDEA 的配置項(xiàng) Settings -> Build, Execution, Deployment -> Debugger -> Stepping
中進(jìn)行配置,如下圖所示。
Step Out
當(dāng)使用 Step In 命令跟蹤到一個(gè)方法的內(nèi)部時(shí),如果發(fā)現(xiàn)自己不想繼續(xù)調(diào)這個(gè)方法了,可以直接把這個(gè)方法執(zhí)行完,并停在調(diào)用該方法的下一行位置,這就是 Step Out 命令。
Drop to Frame
這一招可以說是調(diào)試器的一大殺器。在單步調(diào)試的時(shí)候,如果由于粗心導(dǎo)致單步過了頭,沒有看到關(guān)鍵代碼的執(zhí)行情況,譬如想定位下某個(gè)中間變量的值,這個(gè)時(shí)候如果能回到那行關(guān)鍵代碼再執(zhí)行一遍就好了,Drop to Frame 就提供了我們這個(gè)能力,它可以回到方法調(diào)用的地方(跟 Step Out 不一樣,Step Out 是回到方法調(diào)用的下一行),讓我們可以再調(diào)試一次這個(gè)方法,這一次可不要再粗心了。
Drop to frame 的原理其實(shí)也非常簡(jiǎn)單,顧名思義,它將堆棧的最上面一個(gè)棧幀刪除(也就是當(dāng)前正在執(zhí)行的方法),讓程序回到上一個(gè)棧幀(父方法),可以想見,這只會(huì)恢復(fù)堆棧中的局部變量,全局變量無法恢復(fù),如果方法中有對(duì)全局變量進(jìn)行操作的地方,是沒有辦法再來一遍的。
Run to Cursor / Force Run to Cursor
這兩個(gè)命令在需要臨時(shí)斷點(diǎn)時(shí)非常有用,譬如已經(jīng)知道自己想分析哪一行代碼了,但又不需要下很多無謂的斷點(diǎn),可以直接使用該命令執(zhí)行到某行,F(xiàn)orce Run to Cursor 甚至可以無視所有斷點(diǎn),直接到達(dá)我們想分析的地方。
斷點(diǎn)是調(diào)試器的基礎(chǔ)功能之一,可以讓程序暫停在需要的地方,幫助我們進(jìn)行分析程序的運(yùn)行過程。在 IDEA 中斷點(diǎn)管理如下圖所示,合理使用斷點(diǎn)技巧可以快速讓程序停在我們想停的地方:
可以將斷點(diǎn)分成兩種類型:行斷點(diǎn)指的是在特定的某行代碼上暫停下來,而全局?jǐn)帱c(diǎn)是在某個(gè)條件滿足時(shí)停下來,并不限于停在固定的某一行,譬如當(dāng)出現(xiàn)異常時(shí)暫停程序。
Suspend (All / Thread)
Condition
條件斷點(diǎn)。這應(yīng)該也是每個(gè)使用調(diào)試器的開發(fā)者都應(yīng)該掌握的一個(gè)技巧,當(dāng)遇到遍歷比較大的 List 或 Map 對(duì)象時(shí),譬如有 1000 個(gè) Person 對(duì)象,你不可能每個(gè)對(duì)象都調(diào)一遍,你可能只想在 person.name = 'Zhangsan'
的時(shí)候讓斷點(diǎn)斷下來,就可以使用條件斷點(diǎn),如下圖所示:
Log message to console
Evaluate and log
當(dāng)看到上面的 Suspend 這個(gè)選項(xiàng)的時(shí)候有的人可能會(huì)感到奇怪,我下一個(gè)斷點(diǎn)不就是為了讓程序停下來嗎?還需要這個(gè)選項(xiàng)干什么?是不是有點(diǎn)多余?難道你下個(gè)斷點(diǎn)卻不想讓程序停下來?
在發(fā)現(xiàn) Evaluate and log 這個(gè)技巧之前,我對(duì)這一點(diǎn)也感覺很奇怪,直到有一天我突然發(fā)現(xiàn) Suspend Off + Evaluate and log 的配合真的是太有用了。前面有講過,不要把 System.out.println
當(dāng)作調(diào)試手段,因?yàn)槟阃耆梢杂眠@個(gè)技巧來打印所有你想打印的信息,而不需要修改你的源代碼。
Remove once hit
一次性斷點(diǎn)。上面介紹的 Run to Cursor 就是一次性斷點(diǎn)的例子。
Instance filters
Class filters
Pass count
這幾個(gè)我用的不是很多,但應(yīng)該也是非常有用的技巧可以先記下來。在 IDEA 里每個(gè)對(duì)象都有一個(gè)實(shí)例ID,Instance filters 就是用于當(dāng)斷點(diǎn)處代碼所處的實(shí)例和設(shè)定ID匹配則斷下來。Pass count 則是在斷點(diǎn)執(zhí)行到第幾次的時(shí)候暫停下來。
Exception breakpoints
Method breakpoints
Field watchpoints
個(gè)人感覺這幾個(gè)技巧都不是很常用,感興趣的同學(xué)自己實(shí)驗(yàn)一把吧。
在一堆單步跟蹤的按鈕旁邊,有一個(gè)不顯眼的按鈕,這個(gè)按鈕就是 “求值表達(dá)式”。它在調(diào)試的時(shí)候很有用,可以查看某個(gè)變量的值,也可以計(jì)算某個(gè)表達(dá)式的值,甚至還可以計(jì)算自己的一段代碼的值,這分別對(duì)應(yīng)下面兩種不同的模式:
表達(dá)式模式(Expression Mode)
代碼片段模式(Code Fragment Mode)
這兩個(gè)模式類似于 Eclipse 里面的 Expression View 和 Display View。在 Display View 里也可以編寫一段代碼來執(zhí)行,確實(shí)非常強(qiáng)大,但是要注意的是,這里只能寫代碼片段,不能自定義方法,如下圖:
這個(gè)沒什么好說的,一個(gè)視圖可以查看當(dāng)前的所有線程,另一個(gè)視圖可以查看當(dāng)前的函數(shù)堆棧。在線程視圖里可以進(jìn)行 Thread dump,分析每個(gè)線程當(dāng)前正在做什么;堆棧視圖里可以切換棧幀,結(jié)合右邊的變量觀察區(qū),可以方便的查看每個(gè)函數(shù)里的局部變量和參數(shù)。
線程視圖
堆棧視圖
變量區(qū)和觀察區(qū)可以合并在一起,也可以分開來顯示(如下圖所示),我比較喜歡分開來顯示,這樣局部變量、參數(shù)以及靜態(tài)變量顯示在變量區(qū),要觀察的表達(dá)式顯示在觀察區(qū)。
觀察區(qū)類似于求值表達(dá)式中的 Expression mode,你可以添加需要觀察的表達(dá)式,在調(diào)試的時(shí)候可以實(shí)時(shí)的看到表達(dá)式的值。變量區(qū)的內(nèi)容相對(duì)是固定的,隨著左邊的棧幀調(diào)整,值也會(huì)變得不同。在這里還可以修改變量原有的值。
相信很多人都聽過 gdb,這可以說是調(diào)試界的鼻祖,以前在學(xué)習(xí) C/C++ 的時(shí)候,就是使用它來調(diào)試程序的。和 gdb 一樣,jdb 也是一個(gè)命令行版的調(diào)試器,用于調(diào)試 Java 程序。而且 jdb 不需要安裝下載,它是 JDK 自帶的工具(在 JDK 的 bin 目錄中,JRE 中沒有)。IDEA更多玩法:IntelliJ IDEA內(nèi)容聚合
每研究一項(xiàng)新技術(shù),我總是會(huì)看看有沒有命令行版本的工具可以替代,在命令行下進(jìn)行操作給人一種踏實(shí)的感覺,每一個(gè)指令,每一個(gè)參數(shù),都清清楚楚的擺在那里,這相比較于圖形界面的工具,可以學(xué)習(xí)更深層的知識(shí),而不是把技術(shù)細(xì)節(jié)隱藏在圖形界面之后,你可以發(fā)現(xiàn)命令行下的每一個(gè)參數(shù),每一個(gè)配置,都是可以學(xué)習(xí)的點(diǎn)。
在 jdb 中調(diào)試 Java 程序如下圖所示,直接使用 jdb Test 命令加載程序即可。
運(yùn)行完 jdb Test 命令之后,程序這時(shí)并沒有運(yùn)行起來,而是停在那里等待進(jìn)一步的命令。這個(gè)時(shí)候我們可以想好在哪里下個(gè)斷點(diǎn),譬如在 main() 函數(shù)處下個(gè)斷點(diǎn),然后再使用 run 命令運(yùn)行程序:
> stop in Test.main正在延遲斷點(diǎn)Test.main。將在加載類后設(shè)置。> run運(yùn)行Test設(shè)置未捕獲的 java.lang.Throwable設(shè)置延遲的未捕獲的 java.lang.Throwable>VM 已啟動(dòng):設(shè)置延遲的斷點(diǎn):Test.main
可以看出在執(zhí)行 run 命令之前,程序都還沒有開始運(yùn)行,這個(gè)時(shí)候的斷點(diǎn)叫做“延遲斷點(diǎn)”,當(dāng)程序真正運(yùn)行起來時(shí),也就是 JVM 啟動(dòng)的時(shí)候,才將斷點(diǎn)設(shè)置上。除了 stop in Class.Method
命令,還可以使用 stop at Class:LineNumber
的方式來設(shè)置斷點(diǎn)。
main[1] stop at Test:25
在 jdb 中下斷點(diǎn),就沒有 IDEA 中那么多名堂了,什么條件斷點(diǎn),什么 Instance filters 都不支持,只能乖乖的一步一步來。在斷點(diǎn)處,可以使用 list 命令查看斷點(diǎn)附近的代碼,或者用 step 命令單步執(zhí)行,print 或者 dump 打印變量或表達(dá)式的值,locals 命令查看當(dāng)前方法中的所有變量,cont 命令繼續(xù)執(zhí)行代碼。
還有一些其他的命令就不多做介紹了,可以使用 help 查看所有的命令清單,或者參考 jdb 的官方文檔。IDEA更多玩法:IntelliJ IDEA內(nèi)容聚合
在 jdb 中調(diào)試 Java 程序時(shí),有可能源代碼文件和 class 文件不在一起,這個(gè)時(shí)候需要指定源碼位置:
# jdb -sourcepath path/to/source Test
如果不指定源碼位置,在使用 list 命令時(shí)會(huì)提示找不到源碼文件,如果真的沒有源碼文件,那么在 jdb 里完全就是瞎調(diào)了。我們知道 Java 代碼在執(zhí)行的時(shí)候,是以字節(jié)碼的形式運(yùn)行在 JVM 里的,可以猜測(cè)到,class 文件中必然有著和源碼相關(guān)聯(lián)的一些信息,類似于 C/C++ 語言的 obj 文件一樣,要不然 list 命令怎么可以顯示出當(dāng)前正在執(zhí)行的代碼是哪一行呢?我們可以使用開源的 jclasslib 軟件查看 class 文件里的內(nèi)容,一個(gè)標(biāo)準(zhǔn)的 class 文件包含了下面這些信息:
基本信息
常量池
接口
屬性
父類
字段
方法
Code 屬性
行號(hào)屬性
局部變量表
如下圖所示,其中最重要的一個(gè)部分就是 Code 屬性,Code 屬性下面有行號(hào)屬性 LineNumberTable,這個(gè) LineNumberTable 就是調(diào)試器用來關(guān)聯(lián)字節(jié)碼和源代碼的關(guān)鍵。關(guān)于 class 文件,可以參考:
http://ginobefunny.com/post/deep_in_jvm_notes_part4/
如果沒有源碼,雖然在 jdb 里也可以用 step 來單步,但是沒有辦法顯示當(dāng)前正在運(yùn)行的代碼,這簡(jiǎn)直就是盲調(diào)。這個(gè)時(shí)候只能使用字節(jié)碼調(diào)試工具了,常見的字節(jié)碼調(diào)試器有:Bytecode Visualizer、JSwat Debugger、Java ByteCode Debugger (JBCD) 等等,參考:
https://reverseengineering.stackexchange.com/questions/7991/java-class-bytecode-debugger
通過對(duì) jdb 的學(xué)習(xí),我們已經(jīng)越來越接近 Java 調(diào)試器的真相了,但是還差最后一步。讓我們先看看 Java 程序在 IDEA 里是如何被調(diào)試的,如果你有很強(qiáng)的好奇心,那么在 IDEA 里調(diào)試程序的時(shí)候可能已經(jīng)發(fā)現(xiàn)了下面的秘密:
或者在調(diào)試 tomcat 的時(shí)候,也有類似的一串仿佛魔咒一般的參數(shù):
這串魔咒般的參數(shù)像下面這樣,一旦你理解了這串參數(shù),你也就打破了 Java 調(diào)試器的魔咒,然后才能認(rèn)識(shí)到 Java 調(diào)試器真正的面目:
"C:\Program Files\Java\jdk1.8.0_111\bin\java" -agentlib:jdwp=transport=dt_socket,address=127.0.0.1:20060,suspend=y,server=n FooConnected to the target VM, address: '127.0.0.1:20060', transport: 'socket'
這里面有兩個(gè)關(guān)鍵點(diǎn):
Java 程序在運(yùn)行的時(shí)候帶著 -agentlib
參數(shù),這個(gè)參數(shù)用于指示 JVM 在啟動(dòng)時(shí)額外加載的動(dòng)態(tài)庫文件,-agentlib 參數(shù)和 -javaagent 不一樣,這個(gè)庫文件應(yīng)該是由 C/C++ 編寫的原生程序(JNI),類似于這里的 jdwp,在 Windows 上對(duì)應(yīng)一個(gè) jdwp.dll 庫文件,在 Linux 上對(duì)應(yīng) jdwp.so 文件。那么這個(gè) jdwp 庫文件到底是做什么的呢?它后面的一串參數(shù)又是什么意思?
jdwp 的參數(shù)里貌似提到了 socket,并有 address=127.0.0.1:20060 這樣的 IP 地址和端口號(hào),而且下面的 Connected to the target VM 也似乎表示調(diào)試器連接到了這么一個(gè)網(wǎng)絡(luò)地址,那么這個(gè)地址到底是什么呢?由于這里是本地調(diào)試,所以 IP 地址是 127.0.0.1 ,那么如果是遠(yuǎn)程調(diào)試的話,是不是這里也是支持的呢?
在 IDEA 的 Run/Debug Configuration 配置頁面,你也可以添加一個(gè)遠(yuǎn)程調(diào)試,界面如下圖,可以發(fā)現(xiàn)上面那串魔咒參數(shù)又出現(xiàn)了:
在真正開始遠(yuǎn)程調(diào)試之前,我們不妨帶著這些疑問,來學(xué)習(xí) Java 調(diào)試器的基本原理。IDEA更多玩法:IntelliJ IDEA內(nèi)容聚合
在武俠世界里,天下武功可以分為兩種:一種講究招式新奇,出招時(shí)能出其不意,善于利用兵器的特性和自身的高妙手法攻敵不備;另一種講究內(nèi)功心法,就算是最最普通的招式,結(jié)合自身的深厚內(nèi)力,出招時(shí)也能有雷霆之勢(shì)。其實(shí)在技術(shù)的世界里,武功也可以分為兩種:技巧和原理。
上面講的那么多,無論你是掌握了 IDEA 的所有調(diào)試技巧也好,還是記熟了 jdb 的所有命令也好,都只是招式上的變化,萬變不離其宗,我們接下來就看看調(diào)試器的內(nèi)功心法。
我們知道,Java 程序都是運(yùn)行在 JVM 上的,我們要調(diào)試 Java 程序,事實(shí)上就需要向 JVM 請(qǐng)求當(dāng)前運(yùn)行態(tài)的狀態(tài),并對(duì) JVM 發(fā)出一定的指令,或者接受 JVM 的回調(diào)。為了實(shí)現(xiàn) Java 程序的調(diào)試,JVM 提供了一整套用于調(diào)試的工具和接口,這套接口合在一起我們就把它叫做 JPDA(Java Platform Debugger Architecture,Java 平臺(tái)調(diào)試體系)。
這個(gè)體系為開發(fā)人員提供了一整套用于調(diào)試 Java 程序的 API,是一套用于開發(fā) Java 調(diào)試工具的接口和協(xié)議。本質(zhì)上說,它是我們通向虛擬機(jī),考察虛擬機(jī)運(yùn)行態(tài)的一個(gè)通道,一套工具。
JPDA 由三個(gè)相對(duì)獨(dú)立的層次共同組成,而且規(guī)定了它們?nèi)咧g的交互方式。這三個(gè)層次由低到高分別是 Java 虛擬機(jī)工具接口(JVMTI),Java 調(diào)試線協(xié)議(JDWP)以及 Java 調(diào)試接口(JDI),如下圖所示(圖片來自 IBM developerWorks):
這三個(gè)模塊把調(diào)試過程分解成幾個(gè)很自然的概念:調(diào)試者(debugger)和被調(diào)試者(debuggee),以及他們中間的通信器。被調(diào)試者運(yùn)行于我們想調(diào)試的 Java 虛擬機(jī)之上,它可以通過 JVMTI 這個(gè)標(biāo)準(zhǔn)接口,監(jiān)控當(dāng)前虛擬機(jī)的信息;調(diào)試者定義了用戶可使用的調(diào)試接口,通過這些接口,用戶可以對(duì)被調(diào)試虛擬機(jī)發(fā)送調(diào)試命令,同時(shí)調(diào)試者接受并顯示調(diào)試結(jié)果。
在調(diào)試者和被調(diào)試者之間,調(diào)試命令和調(diào)試結(jié)果,都是通過 JDWP 的通訊協(xié)議傳輸?shù)摹K械拿畋环庋b成 JDWP 命令包,通過傳輸層發(fā)送給被調(diào)試者,被調(diào)試者接收到 JDWP 命令包后,解析這個(gè)命令并轉(zhuǎn)化為 JVMTI 的調(diào)用,在被調(diào)試者上運(yùn)行。類似的,JVMTI 的運(yùn)行結(jié)果,被格式化成 JDWP 數(shù)據(jù)包,發(fā)送給調(diào)試者并返回給 JDI 調(diào)用。而調(diào)試器開發(fā)人員就是通過 JDI 得到數(shù)據(jù),發(fā)出指令。
詳細(xì)的內(nèi)容,可以參考
https://www.ibm.com/developerworks/cn/java/j-lo-jpda1/index.html
到這里,我們已經(jīng)知道了 jdwp 是調(diào)試器和被調(diào)試程序之間的一種通信協(xié)議。不過命令行參數(shù) -agentlib:jdwp=transport=dt_socket,address=127.0.0.1:20060,suspend=y,server=n
中的 jdwp 貌似還不止于此。
事實(shí)上,這個(gè)地方上 jdwp.dll 庫文件把 JDI,JDWP,JVMTI 三部分串聯(lián)成了一個(gè)整體,它不僅能調(diào)用本地 JVMTI 提供的調(diào)試能力,還實(shí)現(xiàn)了 JDWP 通信協(xié)議來滿足 JVMTI 與 JDI 之間的通信。
想要完全理解這串參數(shù)的意思,我們還需要學(xué)習(xí)兩個(gè)概念:Connectors(連接器)和 Transport(傳輸)。
常見的連接器有下面 5 種,它指的是 JDWP 建立連接的方式:
Socket-attaching connector
Shared-memory attaching connector
Socket-listening connector
Shared-memory listening connector
Command-line launching connector
其中 attaching connector 和 listening connector 的區(qū)別在于到底是調(diào)試器作為服務(wù)端,還是被調(diào)試程序作為服務(wù)端。
傳輸指的是 JDWP 的通信方式,一旦調(diào)試器和被調(diào)試程序之間建立起了連接,他們之間就需要開始通信,目前有兩種通信方式:Socket(套接字) 和 Shared-memory(共享內(nèi)存,只用在 Windows 平臺(tái))。
通過上面的學(xué)習(xí)我們了解到,Java 調(diào)試器和被調(diào)試程序是以 C/S 架構(gòu)的形式運(yùn)行的,首先必須有一端以服務(wù)器的形式啟動(dòng)起來,然后另一段以客戶端連接上去。如果被調(diào)試程序以服務(wù)端運(yùn)行,必須加上下面的命令行參數(shù):
# java -agentlib:jdwp=transport=dt_socket,server=y,address=5005 Test# java -agentlib:jdwp=transport=dt_shmem,server=y,address=javadebug Test
第一句是以 socket 通信方式 來啟動(dòng)程序,第二句是以 共享內(nèi)存 的方式來啟動(dòng)程序,socket 方式需要指定一個(gè)端口號(hào),調(diào)試器通過該端口號(hào)來連接它,共享內(nèi)存方式需要指定一個(gè)連接名,而不是端口號(hào)。
在程序運(yùn)行起來之后,可以使用 jdb 的 -attach 參數(shù)將調(diào)試器和被調(diào)試程序連接起來:
# jdb -attach 5005# jdb -attach javadebug
在 Windows 平臺(tái)上,第一條命令會(huì)報(bào)這樣的錯(cuò):java.io.IOException: shmemBase_attach failed: The system cannot find the file specified
,這是由于 jdb -attach 使用系統(tǒng)默認(rèn)的傳輸來建立連接,而在 Windows 上默認(rèn)的傳輸是 共享內(nèi)存 。要想在 Windows 上使用 socket 方式來連接,要使用 jdb -connect 命令,只是命令的參數(shù)在寫法上不太好記憶:
# jdb -connect com.sun.jdi.SocketAttach:hostname=localhost,port=5005# jdb -connect com.sun.jdi.SharedMemoryAttach:name=javadebug
如果反過來,想讓調(diào)試器以服務(wù)端運(yùn)行,執(zhí)行下面的命令:
# jdb -listen javadebug
然后 Java 程序通過下面的參數(shù)來連接調(diào)試器:
# java -agentlib:jdwp=transport=dt_shmem,address=javadebug, suspend=y Test# java -agentlib:jdwp=transport=dt_socket,address=127.0.0.1:5005,suspend=y,server=n
最后我們?cè)倩剡^頭來看一看 IDEA 打印出來的這串魔咒參數(shù),可以大膽的猜測(cè),IDEA 在調(diào)試的時(shí)候,首先以服務(wù)器形式啟動(dòng)調(diào)試器,并在 20060 端口監(jiān)聽,然后 Java 程序以 socket 通信方式連接該端口,并將 JVM 暫停等待調(diào)試。
"C:\Program Files\Java\jdk1.8.0_111\bin\java" -agentlib:jdwp=transport=dt_socket,address=127.0.0.1:20060,suspend=y,server=n FooConnected to the target VM, address: '127.0.0.1:20060', transport: 'socket'
到此,相信大家對(duì)“IntelliJ IDEA遠(yuǎn)程調(diào)試的方法是什么”有了更深的了解,不妨來實(shí)際操作一番吧!這里是創(chuàng)新互聯(lián)網(wǎng)站,更多相關(guān)內(nèi)容可以進(jìn)入相關(guān)頻道進(jìn)行查詢,關(guān)注我們,繼續(xù)學(xué)習(xí)!