Java开源工具在linux上的源码分析(六):符号表的读取

开发 后端
通常我们使用jmap,jstack 去检查堆栈信息的时候,是不会使用-f参数的,但有的时候系统在无法打印出堆栈信息的时候,会建议你使用参数-F。

通常我们使用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 你可以使用不同的参数读取不同的内容。

  1. readelf -s libjvm.so 

显示共享库中的方法参数的虚拟地址,类型,名字

  1. readelf -l libjvm.so 

读取program headers,其中出现2个LOAD的类型,***个是程序的指令虚拟的起始地址,另一个是程序数据的起始地址。

通过2个地址我们就能找到共享库中的参数,函数的相对地址的偏移。

3. 进程中的符号地址

在第二章节中,得到的只是相对的地址偏移,并不是真实运行中的进程的符号地址,如何得到真实的地址在linux中就相对比较简单。

  1. cat /proc/$processid/maps 

在maps里详细记录了进程的堆栈分配的地址,包括共享库的地址,那么起始地址就是这个库分配的最小地址

  1. 进程中共享库分配的最小地址+相对地址的偏移 =真实的进程中该函数或变量的真实地址 

4. Java tool 保存的符号表

在jmap/jstack 中,为了提高读取符号地址的性能,避免每一次要找符号的地址从elf文件中查找,只是在初始话的时候将符号表保存成哈希表,其中key是符号的名字,内容是符号的地址,长度。

具体实现可以参考 /hotspot/src/os/linux/symtab.c build_symtab_internal 函数。

原文链接:http://blog.csdn.net/raintungli/article/details/7289639

【系列文章】

  1. Java开源工具在linux上的源码分析(一):跟踪方式
  2. Java开源工具在linux上的源码分析(二):信号处理
  3. Java开源工具在linux上的源码分析(三):执行的线程vm thread
  4. Java开源工具在linux上的源码分析(四):safe point
  5. Java开源工具在linux上的源码分析(五):-F参数的bug
责任编辑:林师授 来源: raintungli的博客
相关推荐

2012-03-02 12:14:19

JavaJstackJmap

2012-03-02 12:31:50

Javajmapjstack

2012-03-02 12:20:21

Javajmapjstack

2012-03-02 12:25:07

Javajmapjstack

2012-03-02 12:38:49

Javajmapjstack

2014-08-28 10:18:36

LinuxShebang

2017-02-09 20:56:40

iOS符号表支付宝

2024-08-28 10:36:19

2022-06-26 18:09:43

Linux开源

2010-01-27 09:58:59

Linuxunix程序日志

2019-10-16 17:00:51

LinuxUbuntuVMware

2024-04-09 12:49:35

2021-03-09 11:25:04

Linux开源工具服务器

2012-05-22 00:28:21

JavaJava开源开源工具

2022-06-06 14:20:25

个人财务开源预算

2021-09-01 09:47:25

Linux 工具 开发

2021-08-31 09:41:57

LinuxiPhone开源工具

2020-05-09 12:01:40

Linux开源软件SDN

2022-12-19 14:38:59

2019-05-23 14:36:24

LinuxSOSReportxsos
点赞
收藏

51CTO技术栈公众号