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,如需转载请自行联系原作者
目录
相关文章
|
10月前
|
XML 运维 前端开发
LAMP架构调优(四)——资源压缩传输
LAMP架构调优(四)——资源压缩传输
50 2
|
设计模式 架构师 Java
阿里P8架构师都要学习研究的java加强版23种设计模式神级PDF文档
说在前面的话 Java作为老牌纯正的编程语言,在规范性上有着天然优势。因此本版的设计模式讲解全部用Java语言来描述,并针对Java语言的特性对讲解内容做了相当大的改动。 不知道大家是否听过编程界的一段话:掌握设计模式相当于华山派的"气宗",是程序员的内功修为,虽然在同样的学习时间下,类似Python这种"剑宗"的开发模式见效更快,但是长远来看,"气宗"才是走向软件架构师以上级别的必由之路。 所以,掌握气宗就掌握了编程命脉,然而学习设计模式有四大境界: 接下来给大家分享的就是java溢彩加强版大话设计模式包含的内容知识点。 总目录 主要内容 本文是百万销量的经典畅销书《
254 0
|
2月前
|
机器学习/深度学习 安全 算法
十大主流联邦学习框架:技术特性、架构分析与对比研究
联邦学习(FL)是保障数据隐私的分布式模型训练关键技术。业界开发了多种开源和商业框架,如TensorFlow Federated、PySyft、NVFlare、FATE、Flower等,支持模型训练、数据安全、通信协议等功能。这些框架在灵活性、易用性、安全性和扩展性方面各有特色,适用于不同应用场景。选择合适的框架需综合考虑开源与商业、数据分区支持、安全性、易用性和技术生态集成等因素。联邦学习已在医疗、金融等领域广泛应用,选择适配具体需求的框架对实现最优模型性能至关重要。
599 79
十大主流联邦学习框架:技术特性、架构分析与对比研究
|
3月前
|
存储 JavaScript 开发工具
基于HarmonyOS 5.0(NEXT)与SpringCloud架构的跨平台应用开发与服务集成研究【实战】
本次的.HarmonyOS Next ,ArkTS语言,HarmonyOS的元服务和DevEco Studio 开发工具,为开发者提供了构建现代化、轻量化、高性能应用的便捷方式。这些技术和工具将帮助开发者更好地适应未来的智能设备和服务提供方式。
102 8
基于HarmonyOS 5.0(NEXT)与SpringCloud架构的跨平台应用开发与服务集成研究【实战】
|
3月前
|
机器学习/深度学习 算法 数据可视化
基于深度混合架构的智能量化交易系统研究: 融合SSDA与LSTM自编码器的特征提取与决策优化方法
本文探讨了在量化交易中结合时序特征和静态特征的混合建模方法。通过整合堆叠稀疏降噪自编码器(SSDA)和基于LSTM的自编码器(LSTM-AE),构建了一个能够全面捕捉市场动态特性的交易系统。SSDA通过降噪技术提取股票数据的鲁棒表示,LSTM-AE则专注于捕捉市场的时序依赖关系。系统采用A2C算法进行强化学习,通过多维度的奖励计算机制,实现了在可接受的风险水平下最大化收益的目标。实验结果显示,该系统在不同波动特征的股票上表现出差异化的适应能力,特别是在存在明确市场趋势的情况下,决策准确性较高。
105 5
基于深度混合架构的智能量化交易系统研究: 融合SSDA与LSTM自编码器的特征提取与决策优化方法
|
5月前
|
设计模式 前端开发 JavaScript
深入探索研究MVVM架构设计
【10月更文挑战第7天】
101 0
|
10月前
|
缓存 负载均衡 Java
基于微服务架构的后端性能优化研究
基于微服务架构的后端性能优化研究
101 0
|
存储 监控 关系型数据库
ELK架构的应用与研究
ELK架构的应用与研究
175 0
|
3月前
|
弹性计算 API 持续交付
后端服务架构的微服务化转型
本文旨在探讨后端服务从单体架构向微服务架构转型的过程,分析微服务架构的优势和面临的挑战。文章首先介绍单体架构的局限性,然后详细阐述微服务架构的核心概念及其在现代软件开发中的应用。通过对比两种架构,指出微服务化转型的必要性和实施策略。最后,讨论了微服务架构实施过程中可能遇到的问题及解决方案。
|
4月前
|
Cloud Native Devops 云计算
云计算的未来:云原生架构与微服务的革命####
【10月更文挑战第21天】 随着企业数字化转型的加速,云原生技术正迅速成为IT行业的新宠。本文深入探讨了云原生架构的核心理念、关键技术如容器化和微服务的优势,以及如何通过这些技术实现高效、灵活且可扩展的现代应用开发。我们将揭示云原生如何重塑软件开发流程,提升业务敏捷性,并探索其对企业IT架构的深远影响。 ####
99 3

热门文章

最新文章