<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    I want to fly higher
    programming Explorer
    posts - 114,comments - 263,trackbacks - 0
         昨天在公司寫了一段代碼,很簡(jiǎn)單,就是測(cè)試Thread的dumpStack方法的使用。因?yàn)門hread的dumpStack方法不是很常用,但它對(duì)于如果想看看誰(shuí)在運(yùn)行時(shí)調(diào)用方法還是非常有幫助的。回到正題,看輸出結(jié)果:
    java.lang.Exception: Stack trace
     at java.lang.Thread.dumpStack(Unknown Source)
     at Common.getInfo(TestDumpStack.java:21)
     at TestDumpStack.main(TestDumpStack.java:7)
        大家可以看到在輸出的第二行,顯示的是at java.lang.Thread.dumpStack(Unknown Source)。為什么自己寫的代碼就顯示出了源碼文件的名字及所在行數(shù),而jdk的類庫(kù)就顯示出了Unknown Source?
        相信很多人在調(diào)試代碼,用log工具打印堆棧異常信息,查看代碼所在行的相關(guān)調(diào)試信息時(shí),經(jīng)常會(huì)遇到Unknown Source這個(gè)頭痛的問(wèn)題。那么這個(gè)東西到底如何而來(lái)?
        A.Unknown Source從哪來(lái)?

         Unknown Source,顧名思義,就是未知的源文件。因?yàn)槲覀冏罱K解釋運(yùn)行的是class文件,所以出現(xiàn)這個(gè)問(wèn)題的原因很簡(jiǎn)單,就是class文件中沒有源文件的相關(guān)調(diào)試信息。那為什么class文件會(huì)沒有調(diào)試信息呢?答案更簡(jiǎn)單,當(dāng)然是我們?cè)谟胘avac命令進(jìn)行編譯的時(shí)候沒有指定調(diào)試信息唄。因?yàn)楝F(xiàn)在很多人都習(xí)慣用eclipse等一些現(xiàn)成的ide進(jìn)行編寫代碼,所以很少人熟悉jdk自己的javac,java,jdb等一些命令的詳細(xì)參數(shù)(jdk的一些命令和eclipse自帶的一些命令可能不同)。哈哈,不過(guò)如果你經(jīng)常在linux下玩java的話,命令肯定會(huì)非常熟悉。那么讓我們看看javac的一些重要參數(shù):
        -g-Generate all debugging information, including local variables. By default, only line number and source file information is generated.在class文件中生成所有調(diào)試信息,包括局部變量的信息。默認(rèn)的話,只寫入源碼的行號(hào)和源文件信息。
        -g:none-Do not generate any debugging information.不生成任何調(diào)試信息。
        -g:(lines,vars,source)-只生成部分調(diào)試信息(源碼行號(hào),變量,源文件信息)。那我們?cè)诜謩e介紹下lines,vars,source的含義。
             lines:將源文件中的行號(hào)信息寫到Class文件中,此屬性用于在Class文件中生成方法字節(jié)碼流偏移量和源代碼行號(hào)之間的映射關(guān)系。如果我們不指定此屬性的話,我們將在堆棧異常信息中看不到打印的行號(hào)。
             vars:Local variable屬性建立了方法的棧幀中局部變量部分內(nèi)容與源代碼中局部變量名稱和描述符之間的映射關(guān)系。有了這個(gè)屬性,調(diào)試時(shí),我們才可以看到變量的值。
             source:編譯時(shí)指定了這個(gè)屬性,會(huì)把源文件的屬性信息如源文件名稱寫入class文件。
         說(shuō)了這么多,初學(xué)者可能會(huì)迷糊,為什么編譯要指定這些調(diào)試信息呢?哈哈,如果編譯不指定這些調(diào)試信息的話,你怎么調(diào)試呢?如果你不指定行號(hào)信息的話,你在ide中都無(wú)法插入斷點(diǎn)。這些調(diào)試信息在我們調(diào)試程序的時(shí)候非常重要。不過(guò)這些編譯選項(xiàng)通常在ide中如eclipse中早已默認(rèn)了。有的人可能還不相信,打開eclipse,依次打開菜單選項(xiàng):Window->Preferences->Java->Compiler,可以看到頁(yè)面的下方有一個(gè)Classfile Generation,默認(rèn)是四個(gè)選項(xiàng)都選的。
        那這個(gè)Unknown Source到底是編譯的時(shí)候沒有指定哪一項(xiàng)呢?經(jīng)過(guò)測(cè)試,我發(fā)現(xiàn)是javac編譯的時(shí)候沒有沒有指定source選項(xiàng),必定出Unknown Source這個(gè)問(wèn)題。
         PS1:linux下,很多人用ant進(jìn)行javac任務(wù)編譯,查看堆棧異常時(shí)也經(jīng)常會(huì)遇到Unknown Source的問(wèn)題。ant編譯時(shí),默認(rèn)相當(dāng)于指定-g:none,及不生成任何調(diào)試信息的。所以如果要看到日志分析中的源碼和行號(hào)信息時(shí),要更改build.xml中的dubug屬性。
        PS2:我覺得看看Log4j的日志操作類源碼包會(huì)對(duì)這個(gè)理解更有幫助。

        B.剛開始的代碼引子中,為什么自己寫的代碼會(huì)有堆棧異常的代碼行數(shù)顯示,而jdk的類庫(kù)(rt.jar-Runtime Java Archive)代碼會(huì)出現(xiàn)Unknown Source?
        答案很簡(jiǎn)單,因?yàn)槲覀冎苯佑玫氖莏dk直接編譯好的class文件。而rt.jar源碼編譯打包的時(shí)候,是沒有將調(diào)試信息放入class文件的。所以才會(huì)顯示Unknown Source。其實(shí),道理很簡(jiǎn)單,sun的類庫(kù)正常的情況下肯定不會(huì)有bug的,之前肯定都是調(diào)試過(guò)很多遍的,所以沒有必要再加入調(diào)試信息,你只負(fù)責(zé)用就行了。所以,出現(xiàn)Unknown Source很正常。
         PS:其實(shí),我覺得這和軟件的開發(fā)版本差不多。版本一般都有dubug版本和release版本。debug版本就是包含調(diào)試信息的。不過(guò)正式發(fā)行后,肯定不包含調(diào)試信息的。因?yàn)槿绻{(diào)試信息的話,可能版本占用空間會(huì)很大,而且根本就無(wú)需調(diào)試信息。

        C.如果我們非要對(duì)jdk的類庫(kù)如rt.jar進(jìn)行跟蹤調(diào)試怎么辦?
         因?yàn)閞t.jar編譯打包的時(shí)候,是不包含調(diào)試信息的。如果你只是想看看調(diào)用的過(guò)程,你只需要在eclipse中rt.jar下的Source attachment指定jdk安裝目錄的src.zip即可。不過(guò)如果你想跟蹤jdk類庫(kù)的變量值的時(shí)候,這樣就不行了。除非,只有一種辦法,你重新編譯一下src.zip,指定好編譯參數(shù),然后用新編譯好的rt.jar覆蓋掉原來(lái)的rt.jar。這樣就完全ok了。

        D.如果我們想debug其他沒有源代碼的class文件呢?
         其實(shí),也不難,利用jad等反編譯工具編譯出源碼后,在進(jìn)行調(diào)試。不過(guò)前提是該class文件有調(diào)試信息。

         PS:在網(wǎng)上看到了一些打印堆棧異常信息的代碼,發(fā)現(xiàn)有的竟然打印出了jdk源碼的所在行數(shù)。如
    at java.lang.Thread.dumpStack(Thread.java:1206)等。我覺得很好奇,原因可能是重新編譯了jdk的源碼或者可能用的不同的ide或者不同版本的jdk吧。這個(gè)尚需考證。如果有懂的童鞋,可以和我交流

        終于寫完了。可能有很多地方需要改正,希望不吝指教。看了看時(shí)間,是凌晨1:46分。不早了,該睡了。天亮說(shuō)晚安。
    posted on 2011-02-27 01:54 landon 閱讀(39482) 評(píng)論(1)  編輯  收藏 所屬分類: Program

    FeedBack:
    # re: Unknown Source的出現(xiàn)及解決
    2015-03-16 19:26 | he
    看不懂解決方法是甚麼啊  回復(fù)  更多評(píng)論
      
    主站蜘蛛池模板: 91情国产l精品国产亚洲区| 最近2019免费中文字幕视频三| 中文字幕亚洲第一在线| 亚洲高清最新av网站| 国产麻豆视频免费观看| 久久免费视频网站| 青青免费在线视频| 亚洲日本在线电影| 亚洲国产高清美女在线观看| 国产成人亚洲综合无码精品| 国产成人精品123区免费视频| 4虎永免费最新永久免费地址| 精品四虎免费观看国产高清午夜| 羞羞视频免费观看| 亚洲精品无码mⅴ在线观看| 亚洲免费视频网址| 久久精品亚洲精品国产色婷| 亚洲国产精品无码久久一区二区| 国产精品亚洲美女久久久 | 亚洲精品国产日韩无码AV永久免费网| 国产精品免费观看久久| 在线日本高清免费不卡| 99久9在线|免费| 久久久国产精品无码免费专区| 中文在线免费不卡视频| 韩国免费A级毛片久久| 一级特级女人18毛片免费视频| 香港经典a毛片免费观看看| 亚洲爆乳精品无码一区二区| 中文字幕无码精品亚洲资源网久久 | 亚洲精品午夜无码专区| 免费人成网站在线高清| 日本中文一区二区三区亚洲| 国产无遮挡裸体免费视频| 99re热免费精品视频观看| 日本高清在线免费| 永久免费av无码网站韩国毛片| 亚洲人成电影网站免费| 韩国欧洲一级毛片免费| 日本免费v片一二三区| 亚洲国产精品尤物yw在线|