除錯HotSpot原始碼(配視訊)
本文將詳細介紹在Ubuntu16.04 LTS上對OpenJDK8進行編譯,為了方便大家快速搭建起OpenJDK8的除錯開發環境,我還錄製了對應的視訊放到了B站上,大家可以參考。
視訊地址:https://space.bilibili.com/27533329
下面我們開始環境的搭建過程。
之前的文章在Ubuntu 16.04上編譯OpenJDK8的原始碼 已經介紹過在Ubuntu上編譯OpenJDK8的原始碼,這一篇將介紹在Ubuntu上除錯OpenJDK8原始碼的2種方式。
1、GDB除錯原始碼
在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 |
從某個位置開始列印儲存單元的內容,全部當成位元組來看, 而不區分哪個位元組屬於哪個變數 |
2、在Eclipse中除錯原始碼
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進行儲存。
3、在Visual Studio Code中除錯原始碼
在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