JPDA 架构研究18 - JDI的Mirror机制

引入:

上篇文章从整体上来看待JDI协议,这里结合Eclipse的实现代码来讨论下JDI的Mirror机制。

分析:

镜像机制是将目标虚拟机上的所有数据、类型、域、方法、事件、状态和资源,以及调试器发向目标虚拟机的事件请求等都映射成 Mirror 对象。其思想和我们经常说的O/R Mapping一样,其主要思想就是把2个异构的系统中的事物统一起来。

Mirror接口是JDI规范中定义的主接口,它位于com.sun.jdi包中:

public abstract interface Mirror
{
  public abstract String toString();
  public abstract VirtualMachine virtualMachine();
}

这个接口只提供了2个方法,一个是返回该镜像的字符串描述,一个是获取某镜像的实例的虚拟机。

Mirror机制定义了一个庞大的接口hierarchy, com.sun.jdi包中定义的几乎所有接口都直接或者间接继承了Mirror接口,从而把庞大的Debug过程中用到的任何元素,过程,事件都映射起来。

比如基本类型的值被映射为PrimitiveValue, 对象实例被映射为ObjectReference等。

在Eclipse中,它提供了MirrorImpl的镜像实现类,其中获取镜像虚拟机的代码是读取成员变量fVirtualMachineImpl字段,该字段在构造器中初始化:

public MirrorImpl(String description)
  {
    this.fDescription = description;
    this.fVirtualMachineImpl = ((VirtualMachineImpl)this);
    PrintWriter writer = ((VirtualMachineManagerImpl)
      Bootstrap.virtualMachineManager()).verbosePrintWriter();
    if (writer != null)
      this.fVerboseWriter = new VerboseWriter(writer);
  }

虚拟机类提供了许多方法来直接或间接地获取目标虚拟机上所有的数据和状态信息,也可以挂起、恢复、终止目标虚拟机。这样调试器就可以通过某个Mirror,然后间接获得对应虚拟机,并且发送相应指令来完成相应操作了。

时间: 2024-10-12 13:03:57

JPDA 架构研究18 - JDI的Mirror机制的相关文章

JPDA 架构研究19 - JDI的连接模块

引入: 上文提到了JDI的Mirror机制,把整个目标虚拟机上的所有数据.类型.域.方法.事件.状态和资源,以及调试器发向目标虚拟机的事件请求等都映射成Mirror 对象.这里进一步讨论JDI的链接模块. 分析: 连接模块其主要目的是提供调试器(Debugger)到目标虚拟机(Target VM)之间的交互通道. 从连接的发起方来看:连接的发起方可以是调试器,也可以是目标虚拟机. 从连接的数量来看,一个调试器可以连接多个目标VM, 但是一个目标VM只可以连接一个调试器. 我们从调试器(Debug

JPDA 架构研究20 - JDI的事件请求和处理模块

引入: 上文主要讲解了JDI的连接模块来建立Debugger到Target VM之间的连接,这里主要讲解事件请求和处理模块.它们都在com.sun.jdi.event和com.sun.jdi.request包中. 分析: Part 1:查看JDI中定义的事件类型 JDI中事件的接口叫Event . public abstract interface Event extends Mirror {   public abstract EventRequest request(); } 它定义了18种

JPDA 架构研究17 - JDI概览

引入: 前面用了很多篇幅来讨论JVMTI和JDWP部分,现在终于来看最靠近用户端部分了,JDI. 分析: a. JDI的基础知识 和JVMTI和JDWP不一样的是,JDI提供了一组接口,这些接口是纯JAVA编写的.他们主要是给开发环境IDE用的,虽然调试器的实现可以直接利用JDWP或者JVMTI,但是多了这一层则可以从用户的代码级别来定义要发送的请求和获取的信息. 本质上,Eclipse的调试器与目标VM之间的双向通信如下: 调试器将用户的操作转化为调试命令,命令通过链接被发送到前端运行目标程序

JPDA 架构研究1- 整体架构

引入: 关于JPDA(Java Platform Debugger Architecture) 网上有很多讲解,例子.我也不重复发明轮子了,这组文章主要从实践的代码分析角度,仔细剖析这个平台的特点,以及这其中的一些问题澄清和误区. 实践: 如果我们从利用Java Remote Debug的功能来看待JPDA ,并且使用socket的通信方式的话,那么整个过程应该如下: 首先,你在要被调试的服务器上开启远程调试功能.以tomcat 为例: 你要么用命令catalina jpda start,它会启

JPDA 架构研究3 - JDWP层的数据包

引入: 现在我们来看JDWP层的数据包.源码在JDK中很容易找到,它定义$JAVA_HOME/include/jdwpTransport.h 头文件中. 分析: Part 1: 握手过程 (handshake ) 握手包发生在Debugger(JDI端)和Target VM(JVMTI端)的传输层连接建立,并且在发送任何实际数据报之前完成的.它过程如下: a. Debugger会发送14个字节的握手请求到Target VM,这个包的内容是14字节的ASCII字符串 "JDWP-Handshake

JDI 架构研究21 - JDI的Debugger的UI部分

引入: 前面揭示了JDI的Debugger如何建立连接,发送和处理请求,这里我们专注于人机交互部分,Debugger的UI,它主要负责如何把人发出的操作转为请求,以及把请求操作反映在调试器的界面上. 分析: 这个插件主要都定义在org.eclipse.jdt.debug.ui_<Version>.jar中的plugin.xml中,它提供了各种人机交互的插件功能.打的比方,我们看编辑器功能: <extension          point="org.eclipse.ui.ed

JPDA 架构研究2 - JDWP代理

引入: 我们先从最重要的通信层讲起.通信层(JDWP) ,它的全称是Java Debug Wire Protocol.从"Wire"这词就可以看出,它主要是起到"连线"的作用,也就是说,它主要是起到把最靠近程序员的JDI(也就是调试器)和最靠近运行在虚拟机中的程序的JVMTI 连接在一起.因为彼此之间语言不通.比如说JDI这层,我们主要用的eclipse,它是JAVA语言编写的.而JVMTI是用来查询虚拟机状态的,而JAVA虚拟机是用C/C++写的,所以在语言不通的

JPDA 架构研究5 - Agent利用环境指针访问VM (内存管理篇)

引入: 我们在前面说到JVMTI的客户端Agent,又提到Agent通过环境指针来访问VM.这里就来看看环境指针到底有多大的访问VM的能力. 分类1:内存管理 a.Allocate. 分配内存 jvmtiError Allocate(jvmtiEnv* env,             jlong size,             unsigned char** mem_ptr) size:分配的字节数. mem_ptr:分配内存的首地址. b.Deallocate.释放内存,释放已经分配的内

JPDA 架构研究6 - Agent利用环境指针访问VM (线程管理篇)

引入: 上篇文章讲解了分类:内存管理,现在讲线程类操作的接口. 分类2:线程类操作 a.GetThreadState.获取线程状态 jvmtiError GetThreadState(jvmtiEnv* env,             jthread thread,             jint* thread_state_ptr) 大家都知道线程有很多种状态,比如Alive,Terminated,Runnable, 等待进入Synchronize Block,Waiting,Sleepi