java debug体系为什么不能debug到jdk里所有的代码

http://nijiaben.iteye.com/blog/1844115

作为java码农肯定碰到过当我们debug到一些class的时候,发现当进入到某个方法里是看不到声明的入参名,取而代之的是arg0,arg1等,继续深入更是看不到局部变量,这主要是java类编译的时候没有加-g参数导致的,而为什么我们自己在eclipse中写的代码却是可以正常跟踪呢,原因很简单,因为eclipse自行编译的时候是带-g参数编译的。

 

       这种问题在我们安装的jdk中更为常见,为了节省生成的jar空间,于是javac编译都是不带-g参数的,比如rt.jar,里面的类都是不能被正常debug的,因为生成的class信息中没有辅助debug的信息,比如行号,局部变量信息等,那是不是我们通过手动编译jdk即可完全debug jdk中的任意java类呢,答案是否定的。

 

       说到debug,那就要先了解下jdpa体系,jdpa包含三部分,从低到高是jvmti->jdwp->jdi,jvmti是一套本地代码接口,jvm暴露出来的扩展接口,所有的调试功能都是通过其提供出来的,很多jvm性能工具都是基于这些接口来实现的;jdwp是java调试线协议,其主要规范了jvmti和jdi之间的通信协议,比如命令的格式是什么,回复的格式是什么等,当然还包括很多类型的定义,理论上其不包括通信层的实现,通信层的实现可以是socket,也可以是共享内存等;jdi位于最上层,定义了调试器所需要的调试接口,基于这些接口调试器可以方便地了解目标虚拟机的状态信息,大家最熟悉的有eclipse IDE。

    

       那java debug的原理是什么呢,说简单点主要是通过实现jdwp的动态链接库,利用agentlib的机制(其实就是jvmti的扩展机制)在启动或者运行器动态执行动态链接库,-agentlib:jdwp=transport=dt_socket,suspend=y,address=localhost:58140 ,类似如上的启动配置,jdwp是动态链接库的名称,会根据所在的平台自动查找对应的动态库,比如linux下会找到jdwp.so,mac下会找到jdwp.dylib等,至于这个agent怎么实现的就不多说了。

 

       那回过来说说为什么说不能debug到rt.jar中的每行代码呢,该agent往jvmti环境中注册了一个回调方法,回调方法里干了啥呢,比如创建serversocket来等待连接,这主要在我们设置了调试端口,并且suspend=y的情况,该回调方法是在vm初始化完毕之后才去执行的,而在vm初始化的过程中通过启动类加载器已经加载了很多类了,执行了不少java逻辑,所以这些逻辑是根本跟踪不到的,比如sun.misc.Launcher的创建等。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值