您好,登錄后才能下訂單哦!
這期內容當中小編將會給大家帶來有關怎么用源碼分析在linux上符號表的讀取,文章內容豐富且以專業的角度為大家分析和敘述,閱讀完這篇文章希望大家可以有所收獲。
通常我們使用jmap,jstack 去檢查堆棧信息的時候,是不會使用-f參數的,但有的時候系統在無法打印出堆棧信息的時候,會建議你使用參數-F。
關于-F參數與非-F參數的區別筆者已經在前面的博客中講述(http://blog.csdn.net/raintungli/article/details/7023092),簡單的說也就是一種是讓jvm進程自己打印出堆棧信息,另有一種是直接訪問jvm的堆棧區通過固定的結構找出我們需要的信息。
1. Linux-F參數的實現
在linux中可以使用ptrace的系統調用去訪問運行中的進程的內存信息,具體如何實現可以參考筆者的博客(http://blog.csdn.net/raintungli/article/details/6563867)
在java中使用動態加載的方式加載jvm自己的鏈接共享庫,jvm的核心鏈接共享庫是libjvm.so,linux中如何動態加載可以參考(http://www.ibm.com/developerworks/cn/linux/l-dynamic-libraries/#dynamiclinking)
因為是動態共享庫,當想查找具體的參數的值,內存的信息的時候,就需要計算出正確的參數或者函數的地址。
2. 共享庫中的符號相對地址偏移
可運行程序,共享庫使用ELF格式,當運行一個程序的時候,內核會把ELF加載到用戶空間,里面記錄了程序的函數和數據的地址和內容,elf文件格式就不具體描述了。
在linux 中可以使用結構體ELF_EHDR,ELF_PHDR,ELF_SHDR讀出elf 的program header, section header, section data.
在jvm中源碼具體實現請參考 /hotspot/agent/os/linux/salibelf.c
在linux中本身就自帶一個讀取elf格式的工具,readelf 你可以使用不同的參數讀取不同的內容。
readelf -s libjvm.so
顯示共享庫中的方法參數的虛擬地址,類型,名字
readelf -l libjvm.so
讀取program headers,其中出現2個LOAD的類型,***個是程序的指令虛擬的起始地址,另一個是程序數據的起始地址。
通過2個地址我們就能找到共享庫中的參數,函數的相對地址的偏移。
3. 進程中的符號地址
在第二章節中,得到的只是相對的地址偏移,并不是真實運行中的進程的符號地址,如何得到真實的地址在linux中就相對比較簡單。
cat /proc/$processid/maps
在maps里詳細記錄了進程的堆棧分配的地址,包括共享庫的地址,那么起始地址就是這個庫分配的最小地址
進程中共享庫分配的最小地址+相對地址的偏移 =真實的進程中該函數或變量的真實地址
4. Java tool 保存的符號表
在jmap/jstack 中,為了提高讀取符號地址的性能,避免每一次要找符號的地址從elf文件中查找,只是在初始話的時候將符號表保存成哈希表,其中key是符號的名字,內容是符號的地址,長度。
上述就是小編為大家分享的怎么用源碼分析在linux上符號表的讀取了,如果剛好有類似的疑惑,不妨參照上述分析進行理解。如果想知道更多相關知識,歡迎關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。