1. 程式人生 > >除錯HotSpot原始碼(配視訊)

除錯HotSpot原始碼(配視訊)

本文將詳細介紹在Ubuntu16.04 LTS上對OpenJDK8進行編譯,為了方便大家快速搭建起OpenJDK8的除錯開發環境,我還錄製了對應的視訊放到了B站上,大家可以參考。 

視訊地址:https://space.bilibili.com/27533329 

下面我們開始環境的搭建過程。 

之前的文章在Ubuntu 16.04上編譯OpenJDK8的原始碼 已經介紹過在Ubuntu上編譯OpenJDK8的原始碼,這一篇將介紹在Ubuntu上除錯OpenJDK8原始碼的2種方式。 

在Linux上常用GDB除錯C/C++原始碼。使用GDB執行如上例項生成的Class檔案,具體命令如下:

gdb --args ./build/linux-x86_64-normal-server-slowdebug/jdk/bin/java Test

進入GDB後,輸入如下命令: 

break java.c:JavaMain
continue

第一條命令表示在原始檔java.c的JavaMain函式入口處設定斷點;第二條命令表示讓中斷的程式繼續執行,直到執行完程式後退出GDB,並在終端列印”Hello World!“資訊。
下面介紹一些常用的GDB命令,如下表所示。 

命令

描述

backtrace(bt)

檢視各級函式呼叫及引數

finish

連續執行到當前函式返回為止,然後停下來等待命令

frame(f) n

從當前棧幀移到到n棧幀

info(i) locals

檢視當前棧幀區域性變數的值

list(l)

列出原始碼,接著上次的位置往下列,每次列10行ll

list(l)  行號

列出從指定行開始的原始碼

list(l) 函式名

列出指定的函式的原始碼

next(n)

執行下一行語句

print(p)

打印表達式的值,通過表示式可以修改變數的值或者呼叫函式

quit(q)

退出gdb除錯環境

step(s)

執行下一行語句,如果有函式呼叫則進入到函式中

start

開始執行程式,停在main函式第一行語句前面等待命令

break(b) 行號

在指定行設定斷點

break 函式名

在指定函式的開頭設定斷點

break ... if ...

設定條件斷點

continue(c)

從當前位置開始連續執行程式

delete breakpoints 斷點號

刪除斷點

display 變數名

跟蹤檢視指定變數名的變數,每次停下來都顯示它的值

disable breakpoints 斷點號

禁用斷點

enable 斷點號

啟用斷點

info(i) breakpoints

檢視當前設定了哪些斷點

run(r)

從頭開始連續執行程式

undisplay 跟蹤顯示號

取消跟蹤顯示

watch

設定觀察點

info(i) watchpoints

檢視當前設定了哪些觀察點

x

從某個位置開始列印儲存單元的內容,全部當成位元組來看,

而不區分哪個位元組屬於哪個變數

 

1.下載安裝Eclipse並安裝C/C++外掛

在 https://www.eclipse.org/downloads 網站上下載支援Ubuntu 64位版本作業系統的Eclipse,筆者下載的壓縮包名稱為eclipse-java-neon-3-linux-gtk-x86_64.tar.gz,通過如下命令解壓後得到eclipse目錄。命令如下:​

tar -zxvf eclipse-java-neon-3-linux-gtk-x86_64.tar.gz

在執行Eclispe之前還需要配置環境變數,如下: 

export JAVA_HOME=/home/mazhi/workspace/jdk1.7.0_72
export PATH=$PATH:$JAVA_HOME/bin:$JAVA_HOME/jre/bin:$PATH
export CLASSPATH=.:$JAVA_HOME/lib:$JAVA_HOME/jre/lib在

切換到eclipse目錄後,執行如下命令啟動Eclipse。命令如下: 

./eclipse &

啟動Eclipse後,單擊help選單項,選擇Eclipse Marketplace選項後,彈出Eclipse Marketplace對話方塊,搜尋"c++"找到Eclipse C++ IDE..安裝。安裝完成後就可以建立及匯入C/C++專案到Eclipse中了。

或者下載專門開發C/C++的Eclipse整合環境,例如筆者下載的壓縮包名稱為eclipse-cpp-helios-SR1-linux-gtk-x86_64.tar.gz,解壓後以類似的方式啟動。不過在啟動Eclipse之前,需要指定JDK路徑,編譯安裝目錄下的eclipse.ini檔案,如下: 

openFile
-vm
/home/mazhi/workspace/jdk1.7.0_72/bin
-vmargs
-Dosgi.requiredJavaVersion=1.5
-XX:MaxPermSize=256m
-Xms40m
-Xmx384m

在openFile和-vmargs之間配置-vm和/home/mazhi/workspace/jdk1.7.0_72/bin即可。不過通過eclipse-java-neon-3-linux-gtk-x86_64.tar.gz壓縮包安裝的Eclispe需要jdk1.8版本,只需要換個1.8的版本即可。

2.匯入HotSpot原始碼

單擊help選單項,選擇new->Other...後,在彈出的New對話方塊中選擇Makefile Project with Existing Code,然後單擊“Next”,添寫相關的資訊,如下圖所示。​

 

設定完成後單擊“Finish”即可。

3.配置及除錯原始碼

在HotSpot專案上右擊,選擇Debug As -> Debug Configurations...,在彈出的Debug Configurations對話方塊中,選擇C/C++ Application後,右擊,在彈出的選單中選擇New Configuration後,在右側的Main選項卡中配置相關的資訊,如下圖所示。

 切換到Arguments選項卡, 在Program arguments文字框中輸入虛擬機器執行時的引數,這裡執行之前的例項,具體引數如下:

com.test/Test

切換到Environment選項卡, 新增變數:​  

JAVA_HOME=/home/mazhi/workspace/openjdk/build/linux-x86_64-normal-server-slowdebug/jdk/
CLASSPATH=.:/home/mazhi/workspace/project/bin

CLASSPATH指定Test.class檔案所在的目錄。設定完相關資訊後,單擊Apply進行儲存。  

在https://code.visualstudio.com官網上下載Visual Studio Code,筆者下載的是"code_1.51.0-1604600753_amd64.deb"版本。安裝完成後通過單擊File -> OpenFolder選項,選中hotspot資料夾,點選左側導航欄中的Run(Ctrl+Shift+D)圖示切換到對應選項欄,單擊add configuration選項後選中c/c++: (gdb) 啟動,修改lauch.json檔案,所有的配置都通過這個檔案完成,筆者的配置檔案詳細內容如下: 

{
    "version": "0.2.0",
    "configurations": [        
        {
            "name": "HotSpot Linux Debug",
            "type": "cppdbg",
            "request": "launch",
            "program": "/home/mazhi/workspace/openjdk/build/linux-x86_64-normal-server-slowdebug/jdk/bin/java",
            "args": ["com.test/Test"],
            "stopAtEntry": false,
            "cwd": "${workspaceFolder}",
            "environment": [
                {"name":"JAVA_HOME","value":"/home/mazhi/workspace/openjdk/build/linux-x86_64-normal-server-slowdebug/jdk"},
                {"name":"CLASSPATH","value":".:/home/mazhi/workspace/projectjava/projectjava01/bin"}
            ],
            "externalConsole": false,
            "MIMode": "gdb",
            "setupCommands": [
                {
                    "description": "為 gdb 啟用整齊列印",
                    "text": "-enable-pretty-printing",
                    "ignoreFailures": true
                }
            ]
        }
    ]
}

主要關注"configurations"中的"program"、"args"、"environment"配置項,這幾個其實在Eclipse中都指定過,"program"就是指定C/C++應用程式的位置,而"environment"就是配置的環境變數,"args”是為虛擬機器執行配置引數。 

可以在hotspot/src/share/vm/prims/jni.cpp檔案下的JNI_CreateJavaVM()函式上打個斷點,然後在run(Ctrl+Shift+D)選項欄中選中"HotSpot Linux Debug"進行除錯即可。

推薦文章: 

1、在Ubuntu 16.04上編譯OpenJDK8的原始碼(配視訊) 

搭建過程中如果有問題可直接評論留言或加作者微信mazhimazh。

作者持續維護的個人部落格  classloading.com。

關注公眾號,有HotSpot原始碼剖析系列文章!

   

&n