<kbd id="5sdj3"></kbd>
<th id="5sdj3"></th>

  • <dd id="5sdj3"><form id="5sdj3"></form></dd>
    <td id="5sdj3"><form id="5sdj3"><big id="5sdj3"></big></form></td><del id="5sdj3"></del>

  • <dd id="5sdj3"></dd>
    <dfn id="5sdj3"></dfn>
  • <th id="5sdj3"></th>
    <tfoot id="5sdj3"><menuitem id="5sdj3"></menuitem></tfoot>

  • <td id="5sdj3"><form id="5sdj3"><menu id="5sdj3"></menu></form></td>
  • <kbd id="5sdj3"><form id="5sdj3"></form></kbd>

    Java服務(wù)器調(diào)試指南

    共 3238字,需瀏覽 7分鐘

     ·

    2022-07-27 22:18


    在實(shí)際開(kāi)發(fā)中,總會(huì)遇到程序啟動(dòng)不起來(lái)或者運(yùn)行結(jié)果不符合期望的情況,如果是在本地,直接debug就行了,幾乎人人都會(huì),但是如果到了遠(yuǎn)程,大多數(shù)情況下我們可以看日志,通過(guò)日志排查定位到問(wèn)題,但是如果你的日志不多,或者日志中看不出問(wèn)題,此時(shí)情況就比較難以處理了,而實(shí)際上我們?nèi)匀豢梢酝ㄟ^(guò)debug的形式來(lái)解決,只不過(guò)由原來(lái)的本地在ide中通過(guò)GUI來(lái)debug變?yōu)橥ㄟ^(guò)命令行來(lái)debug;


    開(kāi)啟服務(wù)debug端口

    如果想要對(duì)我們遠(yuǎn)程部署的服務(wù)進(jìn)行debug,那么首先我們要開(kāi)啟debug端口,開(kāi)啟方式如下:


    開(kāi)啟遠(yuǎn)程debug:

    在Java啟動(dòng)命令后追加系統(tǒng)參數(shù)-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=8000
    PS:suspend表示是否需要等待遠(yuǎn)程debug連接再開(kāi)始啟動(dòng),y表示需要等待遠(yuǎn)程debug連接才會(huì)繼續(xù)執(zhí)行;

    開(kāi)始debug

    當(dāng)我們的服務(wù)啟動(dòng)后,我們就可以開(kāi)始debug了,此時(shí)有兩種情況:

    • 我們本地可以直接連接到服務(wù)所在的機(jī)器;

    • 我們本地?zé)o法直接連接到服務(wù)所在的機(jī)器;(可能是服務(wù)在容器中、堡壘機(jī)后等)


    如果我們本地可以直接連接到服務(wù)所在的機(jī)器,那么可以在ide中直接選擇遠(yuǎn)程debug,填寫(xiě)好IP和端口號(hào)即可連接上進(jìn)行遠(yuǎn)程debug,與本地debug的體驗(yàn)基本是一致的,沒(méi)什么好講的,我們這里主要說(shuō)說(shuō)本地?zé)o法連接到服務(wù)所在的機(jī)器時(shí)如何進(jìn)行debug;



    當(dāng)我們無(wú)法連接到遠(yuǎn)程服務(wù)所在的機(jī)器時(shí),此時(shí)可以使用jdk中為我們提供的jdb來(lái)調(diào)試,熟悉C語(yǔ)言的可能會(huì)想到gdb,這個(gè)和C語(yǔ)言的gdb是一個(gè)作用,都是用來(lái)讓我們調(diào)試程序的;下面我們來(lái)介紹jdb的詳細(xì)用法:


    jdb詳細(xì)用法

    在遠(yuǎn)程服務(wù)的主機(jī)上使用jdb命令連接到服務(wù),命令如下(如果jdb所在的機(jī)器與服務(wù)所在機(jī)器不一致,需要將127.0.0.1替換為服務(wù)所在機(jī)器的IP,但是注意需要保證jdb所在的機(jī)器可以通過(guò)這個(gè)ip+端口直連到服務(wù)):


    jdb -attach 127.0.0.1:8000



    如果有源碼,可以使用-sourcepath指定源碼,用法與Java指定classpath一致


    jdb -sourcepath /源碼路徑 -attach 127.0.0.1:8000



    使用上述命令進(jìn)入調(diào)試控制臺(tái)后(命令行),我們就可以使用下面這些命令(常用命令)來(lái)調(diào)試我們的應(yīng)用了:


    stop at: 在指定地方斷點(diǎn),例如stop at com.joekerouac.Test:10在com.joekerouac.Test的第10行斷點(diǎn);locals:當(dāng)前堆棧中所有本地變量,包含方法入?yún)ⅲㄗ⒁猓翰话绢?lèi)的成員變量);step:執(zhí)行當(dāng)前行,如果當(dāng)前行調(diào)用了某個(gè)方法,則進(jìn)入方法;step up:執(zhí)行到當(dāng)前方法結(jié)束;next:與step類(lèi)似,不同的是如果當(dāng)前行調(diào)用了某個(gè)方法,會(huì)跳過(guò)方法而不是進(jìn)入方法;cont:執(zhí)行到下個(gè)斷點(diǎn);up:上移線(xiàn)程棧;down:下移線(xiàn)程棧;print: 打印指定變量值;例如一個(gè)方法有一個(gè)參數(shù)叫num,進(jìn)入方法后可以使用print num來(lái)打印num的值;eval:與print類(lèi)似,不同的是這個(gè)支持使用表達(dá)式;where all:打印當(dāng)前所有線(xiàn)程堆棧;where 線(xiàn)程ID:打印指定線(xiàn)程的堆棧,線(xiàn)程ID可以通過(guò)threads獲取;set:修改當(dāng)前某個(gè)變量的值;fields:列出指定類(lèi)的所有字段;list: 查看當(dāng)前所在調(diào)用棧的源碼;


    可以在調(diào)試控制臺(tái)使用help查看jdb支持的完整命令列表及其說(shuō)明;




    簡(jiǎn)單示例


    1、編寫(xiě)一個(gè)Test.java用來(lái)測(cè)試:


    public class Test {
    public static void main(String[] args) { int a = 1; int b = 2; int c = 3; int d = add(a, b, c); int e = add(b, c, d); System.out.println(e); }
    private static int add(int a, int b, int c) { int d = a + b; return d + c; }
    }


    2、編譯

    使用如下命令編譯我們的程序:


    # 注意,這里加了一個(gè)-g選項(xiàng),表示編譯時(shí)攜帶debug信息,否則是沒(méi)辦法正常進(jìn)# 行debug的,對(duì)于我們的服務(wù),使用maven編譯時(shí)自動(dòng)開(kāi)啟了該選項(xiàng),攜帶了debug信# 息,所以我們沒(méi)有主動(dòng)指定;javac -g Test.java


    3、運(yùn)行我們的程序

    使用如下命令運(yùn)行我們的程序:


    # 這里我們開(kāi)啟debug選項(xiàng),并且指定監(jiān)聽(tīng)8000端口,這個(gè)端口可以自行修改java -agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=8000 Test


    運(yùn)行后提示如下:


    4、debug連接

    再開(kāi)一個(gè)shell窗口,在這個(gè)窗口執(zhí)行如下命令進(jìn)行連接:


    # 注意,這里我們運(yùn)行jdb的目錄就是源碼所在目錄,所以源碼目錄使用了當(dāng)前目錄./jdb -sourcepath ./ -attach 127.0.0.1:8000


    運(yùn)行結(jié)果如下:

    5、開(kāi)始debug


    設(shè)置一個(gè)斷點(diǎn)

    使用如下命令設(shè)置一個(gè)斷點(diǎn):


    # 表示在Test類(lèi)的第7行打一個(gè)斷點(diǎn),注意,類(lèi)名要完全限定名,我們這里由于是測(cè)試,# 所以并沒(méi)有包,也不需要添加包名;stop at Test:7


    結(jié)果如下:


    開(kāi)始執(zhí)行

    使用cont指令開(kāi)始執(zhí)行,結(jié)果如下:


    查看源碼

    使用list查看當(dāng)前源碼,結(jié)果如下:

    可以清晰的看到當(dāng)前執(zhí)行到了我們定義的斷點(diǎn)處停止了;


    使用step進(jìn)入方法調(diào)用

    使用step命令進(jìn)入add這個(gè)方法調(diào)用的內(nèi)部,執(zhí)行結(jié)果如下:


    當(dāng)我們使用list查看當(dāng)前斷點(diǎn)上下的源碼時(shí),結(jié)果如下:


    可以看到,當(dāng)前已經(jīng)進(jìn)入方法了(還未執(zhí)行任何行);


    使用locals查看本地變量

    此時(shí)我們可以使用locals來(lái)查看本地變量,因?yàn)檫€未執(zhí)行任何一行,所以本地變量中只有三個(gè)方法參數(shù),結(jié)果如下:


    使用step up來(lái)結(jié)束方法執(zhí)行

    使用step up前我們的調(diào)用棧處于這個(gè)狀態(tài):


    使用step up后會(huì)直接結(jié)束add方法的執(zhí)行,跳回到方法調(diào)用處,結(jié)果如下:


    此時(shí)使用list來(lái)查看,我們回到了主方法中,add方法執(zhí)行完畢,但是還未賦值給d


    使用next來(lái)執(zhí)行當(dāng)前行,并且不進(jìn)入方法調(diào)用


    此時(shí)我們執(zhí)行next,然后執(zhí)行list,會(huì)發(fā)現(xiàn)我們已經(jīng)來(lái)到了第8行,而此時(shí)如果使用step的話(huà),我們?nèi)詴?huì)進(jìn)入add方法中,而此時(shí)我們不想再看add方法的調(diào)用了,可以使用next來(lái)直接跳過(guò)add方法,來(lái)到下一行,結(jié)果如下


    可以看到,當(dāng)我們?cè)诘?行執(zhí)行next的時(shí)候,并沒(méi)有進(jìn)入add方法內(nèi)部,而是直接將其執(zhí)行完畢來(lái)到了第9行;


    此時(shí)再使用locals命令查看變量,此時(shí)會(huì)打印出args這個(gè)main方法的入?yún)⒑蚢、b、c、d、e這5個(gè)本地變量,結(jié)果如下


    使用set命令修改e的值

    此時(shí)我們可以使用set命令來(lái)修改e的值,運(yùn)行結(jié)果如下:

    可以發(fā)現(xiàn)此時(shí)e已經(jīng)是12了


    打印當(dāng)前線(xiàn)程棧

    使用where all打印所有線(xiàn)程棧



    使用where 線(xiàn)程ID打印指定線(xiàn)程棧

    先使用threads獲取線(xiàn)程ID:


    然后使用where 線(xiàn)程ID來(lái)打印指定線(xiàn)程棧:


    可以看到,當(dāng)前main線(xiàn)程正處于Test的第9行,而這與我們實(shí)際運(yùn)行的也是一致的


    聯(lián)系我

    • 作者微信:JoeKerouac

    • 微信公眾號(hào)(文章會(huì)第一時(shí)間更新到公眾號(hào),如果搜不出來(lái)可能是改名字了,加微信即可=_=|):代碼深度研究院

    • GitHub:https://github.com/JoeKerouac


    瀏覽 77
    點(diǎn)贊
    評(píng)論
    收藏
    分享

    手機(jī)掃一掃分享

    分享
    舉報(bào)
    評(píng)論
    圖片
    表情
    推薦
    點(diǎn)贊
    評(píng)論
    收藏
    分享

    手機(jī)掃一掃分享

    分享
    舉報(bào)

    <kbd id="5sdj3"></kbd>
    <th id="5sdj3"></th>

  • <dd id="5sdj3"><form id="5sdj3"></form></dd>
    <td id="5sdj3"><form id="5sdj3"><big id="5sdj3"></big></form></td><del id="5sdj3"></del>

  • <dd id="5sdj3"></dd>
    <dfn id="5sdj3"></dfn>
  • <th id="5sdj3"></th>
    <tfoot id="5sdj3"><menuitem id="5sdj3"></menuitem></tfoot>

  • <td id="5sdj3"><form id="5sdj3"><menu id="5sdj3"></menu></form></td>
  • <kbd id="5sdj3"><form id="5sdj3"></form></kbd>
    小泽玛利亚性爱视频 | 三及片在线观看 | 色婷婷亚洲精品天 | 国产爽爽操逼91 | 国产久久视频 |