BTrace原理浅析
BTrace一直以来都是很方便的调试跟找错工具,最近得空简单翻阅了一下他的源码,对BTrace的工作原理做了一下大概的总结,具体如下:
agent端
在com.sun.btrace.agent包下面都是agent中的代码,其中我们从Main这个类跟踪进去就会发现,Btrace在启动的时候大概做了以下几个事情:
1.加载、解析调用的参数
2.创建一个agentThread,其中就包括了启动服务端的调用
Thread agentThread = new Thread(new Runnable() {
@Override
public void run() {
BTraceRuntime.enter();
try {
startServer();
} finally {
BTraceRuntime.leave();
}
}
});
3.在startServer方法中具体会做以下几件事
- 通过指定端口创建一个ServerSocket并监听他
- 一旦收到来自客户端的请求会调用handleClient方法进行处理,并且读取来自客户端提交的代码进行字节码转换
- 从所有已经加载的class进行筛选,过滤出我们需要进行监听的class
- 对筛选出的class调用Instrumentation中的retransformClasses方法,对这些类进行重新加载
Client端
- 同样会解析参数,具体来决定是否debug,是否输入到文件等等
- 创建一个client对象,并且调用VirtualMachine.attach(pid);方法来获取一个指定pid的JVM对象
- 调用vm.loadAgent, 其实这里就是将包含server部分代码的agent给load到我们的java虚拟机中
- 编译java代码,这里细节就不表了,就是将java文件编译为byte[]形式做后续调用
- 注册一些jvm退出时候的hook,譬如在按下crtl+c的时候会有一个选择菜单就是在这里注册的,拦截了一些系统信号
- socket连接到服务器端,将编译好的code byte数组提交到服务端