Java远程调试,它在技术上是如何工作的?
我真的很喜欢JVM的远程调试功能。但我想知道它是如何在内部运作的。
我的假设:它是通过JVM功能完成的,其中正在运行的进程正在从附加的远程调试器(如IDE)下载/使用源代码,它知道当前堆栈跟踪的行,然后可以跳转到相应的IDE断点。然后,堆栈跟踪的通信和应用程序状态的内省通过套接字或共享内存(远程调试器的设置)完成。
有没有人对此感兴趣的链接/资源?
我真的很喜欢JVM的远程调试功能。但我想知道它是如何在内部运作的。
我的假设:它是通过JVM功能完成的,其中正在运行的进程正在从附加的远程调试器(如IDE)下载/使用源代码,它知道当前堆栈跟踪的行,然后可以跳转到相应的IDE断点。然后,堆栈跟踪的通信和应用程序状态的内省通过套接字或共享内存(远程调试器的设置)完成。
有没有人对此感兴趣的链接/资源?
JVM 的调试功能通过 Java 平台调试器体系结构 (JPDA) 提供。
JPDA本身由以下内容组成:
JPDA 架构结构中列出的图是一个很好的起点。要查找的其他位置是JPDA页面中列出的指南。
Eclipse 调试从所谓的代理开始。
运行编译的“.class”源的 JVM 具有一个功能,允许在运行时将外部库(用 Java 或 C++ 编写)注入到 JVM 中。这些外部库称为代理,它们能够修改已运行.class文件的内容。这些代理可以访问JVM的功能,这些功能无法从JVM内部运行的常规Java代码中访问,并且它们可用于执行有趣的操作,例如注入和修改正在运行的源代码,分析等。一些工具,如JRebel(用于热替换代码)利用这一功能来实现它们的魔力。
要将代理库传递给 JVM,您可以通过启动参数执行此操作,使用 -
agentlib:libname[=options]
我们实际上是将一个名为 jdwp 的代理 Lib 传递给运行 Tomcat 的 JVM。jdwp 是 JDWP(Java Debug Wire Protocol)的特定于 JVM 的可选实现,用于定义调试器和正在运行的 JVM 之间的通信。它是实现的,如果存在作为JVM的本机库作为 jdwp.so 或jdwp提供.dll
那么它有什么作用呢?简单来说,我们传递的 jdwp 代理基本上是作为运行应用程序的 JVM 实例和调试器(可以位于远程或本地)之间的链接的功能。由于它是一个代理库,因此它确实能够拦截正在运行的代码,在JVM和调试器之间创建桥梁,并在JVM上应用调试器的功能。由于在JVM架构中,调试功能不是在JVM本身中找到的,而是被抽象到外部工具(被恰当地称为调试器)中,因此这些工具可以驻留在运行正在调试的JVM的本地机器上,也可以从外部机器运行。正是这种非耦合的模块化架构允许我们在远程机器上运行JVM并使用JDWP,让远程调试器能够与之通信。
简而言之,这就是Eclipse调试器的工作方式。