JPDA 架构研究4 - JDWP的传输器

简介:

引入:

上一篇文章主要分析JDWP层传输的数据包的格式,这篇文章我们主要关注于JDWP层是如何传输的。


分析:

传输的具体实现是根据各个JVM自己实现,但是他们有个共同点就是都是用C/C++实现的,并且都实现了jdwpTransport.h (和上篇一样的这个文件)。实现根据我们的知识可以得知是以dll文件(或者Unix平台下是so文件)的形式存在。因为我们从前面了解到,JDWP层有Agent负责在数据包和JVMTI的函数调用之间转换,所以顺理成章知道,传输层的DLL文件也必定会有一个onload方法,并且让Agent启动时候调用的。



分析1:Agent如何访问VM环境呢?

答案是通过环境指针(environment pointer), 该指针会在onload()方法中返回给Agent.这个环境指针的定义如下:

1
2
3
4
5
6
7
8
struct  _jdwpTransportEnv;
 
#ifdef __cplusplus
typedef  _jdwpTransportEnv jdwpTransportEnv;
 
...
struct  _jdwpTransportEnv {
     const  struct  jdwpTransportNativeInterface_ *functions;

所以这里可以看出,环境指针本质就是拿到一组可以访问目标VM环境的native接口。


分析2:Agent启动时调用的onload()方法。

当Target VM加载了Agent之后,JDWP会根据参数去加载具体的JDWP的实现,Sun 的 JDK 在 Windows 提供 socket 和 share memory 两种传输方式,而在 Linux 上只有 socket 方式)。传输层实现的动态链接库实现必须暴露 jdwpTransport_OnLoad 接口,来对传输层初始化。

该方法签名如下:

1
2
3
4
5
JNIEXPORT jint JNICALL 
jdwpTransport_OnLoad(JavaVM *jvm,
                      jdwpTransportCallback *callback,
                      jint version,
                      jdwpTransportEnv** env);

从这里可以看出_OnLoad方法需要下面几个入参:

jvm: 它让Agent通过GetJavaVM方法来获取JVM信息。

callback:它是一个函数表的指针,传输层用它来进行内存的分配与释放。

version:它让Agent获得期望的JDWPTRANSPORT的版本。

然后返回值就是在第四个参数中,它就是我们想要的环境指针。

如果传输层初始化成功,那么_OnLoad方法就会返回JNI_OK,否则会返回对应的错误码。


分析3:jdwpTransport支持的方法概览。

因为jdwpTransport需要维系着Debugger和Target VM之间的关系,所以它有许多方法。我们从几大类来看。


分类1:用于管理连接

管理连接的方法其主要作用是用于建立和关闭到Debugger的连接。

a. Attach.它主要用于关联到Debugger,建立到Debugger之间的可信链路.

步骤1:连接到指定的地址

步骤2:连接成功,则通过交换 ”JDWP-Handshake"来确保到Debugger的连接的确被建立。

1
2
3
4
5
     /*  3 : Attach */
     jdwpTransportError (JNICALL *Attach)(jdwpTransportEnv* env,
         const  char * address,
         jlong attach_timeout,
         jlong handshake_timeout);

从这里可以看出,除了环境指针外,它需要下面3个参数:

address: Debugger的地址和端口

attach_timeout:设置连接超时值,单位毫秒。如果设为0则说明永不超时。

handshake_timeout:设置握手超时值,单位毫秒。如果设为0则说明永不超时。


b.StartListening.它主要用于让传输器处于listen模式,这样它就可以监听来自Debugger的连接了。

1
2
3
4
   /*  4: StartListening */
     jdwpTransportError (JNICALL *StartListening)(jdwpTransportEnv* env,
         const  char * address,
         char ** actual_address);

除环境指针外,它还需要1个参数:

address:Debugger的地址和端口

actualAddress:返回值,返回传输器从address参数获得的真实字符串形式的地址。


c.StopListening.它主要用于让传输器离开listen模式,这样它就不再监听来自Debugger的连接了。

1
2
     /*  5: StopListening */
     jdwpTransportError (JNICALL *StopListening)(jdwpTransportEnv* env);


d.Accept.它主要用于建立来自Debugger的连接。

1
2
3
4
  /*  6: Accept */
     jdwpTransportError (JNICALL *Accept)(jdwpTransportEnv* env,
         jlong accept_timeout,
         jlong handshake_timeout);


e.IsOpen.它用于测试Debugger的连接是否开着。

1
2
    /*  7: IsOpen */
     jboolean (JNICALL *IsOpen)(jdwpTransportEnv* env);


f.Close.它用于关闭到Debugger的连接。

1
2
    /*  8: Close */
     jdwpTransportError (JNICALL *Close)(jdwpTransportEnv* env);



分类2:用于读来自Debugger的数据包和发送到Debugger的数据包。

a. ReadPacket. 它用于在连接开着的状态,从Debugger读取数据包。

1
2
3
   /*  9: ReadPacket */
     jdwpTransportError (JNICALL *ReadPacket)(jdwpTransportEnv* env,
         jdwpPacket *pkt);

需要注意的是,该方法只对数据包做长度校验,而不做完整性校验。


b.WritePacket.它用于在连接开着的状态,往Debugger写数据包。

1
2
3
   /*  10: Write Packet */
     jdwpTransportError (JNICALL *WritePacket)(jdwpTransportEnv* env,
         const  jdwpPacket* pkt);


分类3:辅助功能。

a.GetLastError.它用于返回用字符串表示的上次错误。

1
2
3
     /*  11:  GetLastError */
     jdwpTransportError (JNICALL *GetLastError)(jdwpTransportEnv* env,
         char ** error);


b.GetCapabilities.它用于返回JDWP传输器所有支持的能力。

1
2
3
  /*  2 : Get Capabilities */
     jdwpTransportError (JNICALL *GetCapabilities)(jdwpTransportEnv* env,
          JDWPTransportCapabilities *capabilities_ptr);

能力的启用和禁用是通过一组位图位来标示的。


整个传输器的架构如下:

wKioL1SJKfygLz4kAAExNZHnNuU512.jpg





本文转自 charles_wang888 51CTO博客,原文链接:http://blog.51cto.com/supercharles888/1587625,如需转载请自行联系原作者
目录
相关文章
|
30天前
|
XML 运维 前端开发
LAMP架构调优(四)——资源压缩传输
LAMP架构调优(四)——资源压缩传输
14 2
|
6月前
|
设计模式 架构师 Java
阿里P8架构师都要学习研究的java加强版23种设计模式神级PDF文档
说在前面的话 Java作为老牌纯正的编程语言,在规范性上有着天然优势。因此本版的设计模式讲解全部用Java语言来描述,并针对Java语言的特性对讲解内容做了相当大的改动。 不知道大家是否听过编程界的一段话:掌握设计模式相当于华山派的"气宗",是程序员的内功修为,虽然在同样的学习时间下,类似Python这种"剑宗"的开发模式见效更快,但是长远来看,"气宗"才是走向软件架构师以上级别的必由之路。 所以,掌握气宗就掌握了编程命脉,然而学习设计模式有四大境界: 接下来给大家分享的就是java溢彩加强版大话设计模式包含的内容知识点。 总目录 主要内容 本文是百万销量的经典畅销书《
119 0
|
8月前
|
存储 监控 关系型数据库
|
8月前
|
存储 人工智能 Cloud Native
云原生大数据架构实践与思考-DataFunTalk
导读: 作者:振策-阿里云计算平台-产品解决方案, 20230805 本文将分享当前云原生大数据架构的发展历程/架构定义/核心能力/应用场景及趋势思考。主要包括以下四个部分: - 从大数据上云看架构 - 云原生数据平台的核心能力 - Data+AI with Cloud-Native - 未来趋势与思考
1314 0
|
11月前
|
数据采集 机器学习/深度学习 设计模式
卷麻了! nnUNet 研究团队重磅新作 | MedNeXt: 新一代分割架构之王,刷新多项榜单记录!
卷麻了! nnUNet 研究团队重磅新作 | MedNeXt: 新一代分割架构之王,刷新多项榜单记录!
550 0
|
11月前
|
SQL 存储 缓存
图解MySQL系列(2)-SQL实战研究InnoDB架构设计
业务系统通过一个数据库连接发给MySQL,经过SQL接口、解析器、优化器、执行器,解析SQL语句,生成执行计划,接着由执行器负责执行该计划,调用InnoDB的接口去实际执行。
155 0
|
存储 缓存 NoSQL
【Laravel框架】对于Laravel框架架构的研究以及视图方法和内置会话在项目里的运用
【Laravel框架】对于Laravel框架架构的研究以及视图方法和内置会话在项目里的运用
255 0
【Laravel框架】对于Laravel框架架构的研究以及视图方法和内置会话在项目里的运用
|
存储 运维 负载均衡
基于网关服务治理的研究与实践(一)微服务架构
本篇原创系列是对基于网关服务治理的开篇介绍,作为服务治理的引子,介绍了目前主流的微服务架构技术,包括微服务架构的概念与优势、服务注册与发现、服务路由与负载均衡、服务安全等内容。
1337 0
基于网关服务治理的研究与实践(一)微服务架构
|
11天前
|
API 数据库 开发者
构建高效可靠的微服务架构:后端开发的新范式
【4月更文挑战第8天】 随着现代软件开发的复杂性日益增加,传统的单体应用架构面临着可扩展性、维护性和敏捷性的挑战。为了解决这些问题,微服务架构应运而生,并迅速成为后端开发领域的一股清流。本文将深入探讨微服务架构的设计原则、实施策略及其带来的优势与挑战,为后端开发者提供一种全新视角,以实现更加灵活、高效和稳定的系统构建。
18 0
|
9天前
|
Kubernetes 安全 Java
构建高效微服务架构:从理论到实践
【4月更文挑战第9天】 在当今快速迭代与竞争激烈的软件市场中,微服务架构以其灵活性、可扩展性及容错性,成为众多企业转型的首选。本文将深入探讨如何从零开始构建一个高效的微服务系统,覆盖从概念理解、设计原则、技术选型到部署维护的各个阶段。通过实际案例分析与最佳实践分享,旨在为后端工程师提供一套全面的微服务构建指南,帮助读者在面对复杂系统设计时能够做出明智的决策,并提升系统的可靠性与维护效率。