反向 Debug 了解一下?揭秘 Java DEBUG 的基本原理


以一
以一 2024-01-07 17:43:15 63699 赞同 0 反对 0
分类: 资源
Debug 的时候,都遇到过手速太快,直接跳过了自己想调试的方法、代码的时候吧…… 一旦跳过,可能就得重新执行一遍,准备数据、重新启动可能几分钟就过去了。 好在IDE 们都很强大,还给你后悔的机会,可以直接删除某个 Stack Frame,直接返回到之前的状态,确切的说是返回到之前的某个 Stack Frame,从而实现让程序“逆向运行”。

Debug 的时候,都遇到过手速太快,直接跳过了自己想调试的方法、代码的时候吧……

一旦跳过,可能就得重新执行一遍,准备数据、重新启动可能几分钟就过去了。

好在IDE 们都很强大,还给你后悔的机会,可以直接删除某个 Stack Frame,直接返回到之前的状态,确切的说是返回到之前的某个 Stack Frame,从而实现让程序“逆向运行”。

反向 Debug 了解一下?揭秘 Java DEBUG 的基本原理

这个 Reset Frame 的能力,可不只是返回上一步,上 N 步也是可以的;选中你期望的那个帧,直接Reset Frame/Drop Frame,可以直接回到调用栈上的某个栈帧,时间反转!

可惜这玩意也不是那么万能,毕竟是通过 stack pop 这种操作实现,实际上只是给调用栈栈顶的 N 个 frame pop 出来而已,还谈不上是真正的“反向 DEBUG”。

相比之下, GDB 的 Reverse Debugging 就比较强大,真正的 “反向” DEBUG,逆向运行,实现回放。

所以吧在运行过程中,已经修改的数据,比如引用传递的方法参数、变量,一旦修改肯定回退不了,不然真的成时光机了。

这些乱七八糟的调试功能,都是基于 Java 内置的 Debug 体系来实现的。

JAVA DEBUG 体系

Java 提供了一个完整的 Debug 体系 JPDA (Java Platform Debugger Architecture),这个 JPDA 架构体系由 3 部分组成:

  • JVM TI – Java VM Tool Interface
  • JDWP – Java Debug Wire Protocol
  • JDI – Java Debug Interface

如果结合IDE 来看,那么一个完整的 Debug 功能看起来就是这个样子:

反向 Debug 了解一下?揭秘 Java DEBUG 的基本原理

解释一下这个体系:

JVM TI 是一个 JVM 提供的一个调试接口,提供了一系列控制 JVM 行为的功能,比如分析、调试、监控、线程分析等等。也就是说,这个接口定义了一系列调试分析功能,而 JVM 实现了这个接口,从而提供调试能力。

不过吧,这个接口毕竟是 C++的,调用起来确实不方便,所以Java 还提供了 JDI 这么个 Java 接口。

JDI 接口使用 JDWP 这个私有的应用层协议,通过 TCP 和目标 VM 的 JVMTI 接口进行交互。

也可以把简单这个 JDWP 协议理解为 JSF/Dubbo 协议;相当于 IDE 里通过 JDI 这个 SDK,使用 JDWP 协议调用远程 JVMTI 的 RPC 接口,来传输调试时的各种断点、查看操作。

可能有人会问,搞什么套壳!要什么 JDWP,我直接 JVMTI 调试不是更香,链路越短性能越高!

当然可以,比如 Arthas 里的部分功能,就直接使用了 JVMTI 接口,要什么 JDI!直接 JVMTI 干就完了。

开个玩笑,Arthas 毕竟不是 Debug 工具,人家根本就不用 JDI 接口。而且 JVMTI 的能力也不只是断点,它的功能非常多:

反向 Debug 了解一下?揭秘 Java DEBUG 的基本原理

左边的功能类,提供了各种乱七八糟的功能,比如我们常用的添加一个断点:

jvmtiError
SetBreakpoint(jvmtiEnv* env,
            jmethodID method,
            jlocation location)

右边的事件类,可以简单的理解为回调;还是拿断点举例,如果我用上面的 SetBreakpoint 添加了一个断点,那么当执行到该位置时,就会触发这个事件:

void JNICALL
Breakpoint(jvmtiEnv *jvmti_env,
            JNIEnv* jni_env,
            jthread thread,
            jmethodID method,
            jlocation location)

JVMTI 的功能非常之多,而 JDI 只是实现了部分 JVMTI 的方法,所以某些专业的 Profiler 工具,可能会直接使用 JVMTI,从而实现更丰富的诊断分析功能。

远程调试与本地调试

不知道大家有没有留意过本地 Debug 启动时的日志:

反向 Debug 了解一下?揭秘 Java DEBUG 的基本原理

第一行是隐藏了后半段的启动命令,展开后是这个样子:

/path/to/java -agentlib:jdwp=transport=dt_socket,address=127.0.0.1:53631,suspend=y,server=n -javaagent:/path/to/jetbrains/debugger-agent.jar ...

第二行是一个 Connected 日志,意思是使用 socket 连接到远程 VM 的53631端口

上一段说到,IDE 通过 JDI 接口,使用 JDWP 协议和目标 VM 的 JVMTI 交互。这里的 53631 端口,就是目标 JVM 暴露出的 JVM TI 的 server 端口。

而第一行里,IDEA 自动给我们加上了 -agentlib:jdwp=transport=dt_socket,address=127.0.0.1:53631 这么一段,这个参数的意思就是,让 jvm 以 53631 暴露 jdwp 协议

小知识,这个 agentlib 可不只是为 jvmti 提供的。它还可以让 JVM 加载其他的 native lib包,直接“”到你的 jvm 上,下面是参数格式:

反向 Debug 了解一下?揭秘 Java DEBUG 的基本原理

所以吧,上面的描述其实不太严谨,更专业的说法是:

让 JVM 加载 JDWP 这个 agent 库,参数为transport=dt_socket,address=127.0.0.1:53631 ,这个 jdwp agent 库以 53631 端口提供了 jdwp 协议的 server。只不过这个 jdwp 是jvm 内部的库,不需要额外的 so/dylib/dll 文件。

如有需要,你完全可以弄个 “datupiao” 的 agentlib,”到这个 jvm 上,然后在这个 lib 里调用 JVMTI 接口,然后暴露个端口提供服务和远程交互,实现自己的 jdwp!

可能某些老板们注意到了,本地调试还要127.0.0.1走tcp 交互一遍,那远程调试呢?

基于上面的解释,本地调试和远程调试真的没啥区别!或者说,在目前 IDEA/Eclipse 的实现下,不存在本地调试,都是远程!只不过一个是 127.0.0.1,一个是远程的 IP 而已。

在本地调试时,IDEA 会自动给我们的 JVM 增加 agent 参数,随机指定一个端口,然后通过 JDI 接口连接,代码大概长这样(JDI 的 SDK 在 JDK_HOME/lib/tools.jar ):

Map env = connector.defaultArguments();
env.get("hostname").setValue(hostname);
env.get("port").setValue(port);

VirtualMachine vm = connector.attach(env);

瞅瞅, VirtualMachine 里的就这点方法,能力上比 JVMTI 还是差远了

List classesByName(String className);

 


List allClasses();


void redefineClasses(Map



                                                        

本文来自网络

 

如果您发现该资源为电子书等存在侵权的资源或对该资源描述不正确等,可点击“私信”按钮向作者进行反馈;如作者无回复可进行平台仲裁,我们会在第一时间进行处理!

评价 0 条
以一L0
粉丝 0 资源 1143 + 关注 私信
最近热门资源
麒麟系统版本介绍白皮书  515
MiSans 阿拉伯语字体文件  458
解决新版本麒麟系统中微信打开白屏显示  400
麒麟系统进行系统监控,查看进程的运行时间来优化性能  332
临时关闭swap分区与永久关闭swap分区(注意必须确保系统有足够内存运行!)  224
统信桌面专业版添加字体  217
统信uos单一程序黑屏,任务栏正常显示解决办法  216
统信uos快捷键文档  187
统信系统双无线网卡设置关闭开启单一网卡  145
分享一个磁盘恢复工具,适用于多平台(包括统信)  122
最近下载排行榜
麒麟系统版本介绍白皮书 0
MiSans 阿拉伯语字体文件 0
解决新版本麒麟系统中微信打开白屏显示 0
麒麟系统进行系统监控,查看进程的运行时间来优化性能 0
临时关闭swap分区与永久关闭swap分区(注意必须确保系统有足够内存运行!) 0
统信桌面专业版添加字体 0
统信uos单一程序黑屏,任务栏正常显示解决办法 0
统信uos快捷键文档 0
统信系统双无线网卡设置关闭开启单一网卡 0
分享一个磁盘恢复工具,适用于多平台(包括统信) 0
作者收入月榜
1

prtyaa 收益399.62元

2

zlj141319 收益236.11元

3

IT-feng 收益219.61元

4

1843880570 收益214.2元

5

风晓 收益208.24元

6

哆啦漫漫喵 收益204.5元

7

777 收益173.07元

8

Fhawking 收益106.6元

9

信创来了 收益106.03元

10

克里斯蒂亚诺诺 收益91.08元

请使用微信扫码

添加我为好友,拉您入交流群!

请使用微信扫一扫!