# Arthas运行原理

jdk1.5增加了java.lang.instrument,提供底层组件的访问能力,要求在运行前利用命令行或系统参数设置代理类,vm启动后,初始化

  1. premain函数
  2. 打包,制定premain-class
  3. 使用-javaagent启动

jdk1.6后,增加agentmain函数,之后通过addTransformer retransformclasses redefineClasses等对字节码增加

Jvmti(JVM Tool Interface)native接口,提供debug与profiler能力,实现调试器和其它运行态分析工具的基础,instrument就是对它的封装

动态attach步骤 VirtualMachine.attach(pid)

public static void agentmain(String args, Instrumentation inst) throws Exception 
    {
        System.out.println("Args:" + args);
    }
    
    public static void premain(String args, Instrumentation inst) throws Exception 
    {
        System.out.println("Pre Args:" + args);
        Class[] classes = inst.getAllLoadedClasses();
        for (Class clazz : classes) 
        {
           System.out.println(clazz.getName());
        }
    } 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
  1. 加载libattach.so
  2. 创建attach_pid文件
  3. 发送sigquit信息
  4. jvm创建一个路径为/tmp/.java_pid的unix socket
  5. 建立连接

想要Arthas代码与应用的代码可同时获取到JMX等系统级的API,同时两者之间的代码是完全隔离的, ArthasClassLoader与AppClassLoader就必须共用同一个parent:ExtClassLoader,且两者要互相分属不同的ClassLoader

// Arthas源码:
public class ArthasClassloader extends URLClassLoader {
    public ArthasClassloader(URL[] urls) {
        super(urls, ClassLoader.getSystemClassLoader().getParent());
    }
}
1
2
3
4
5
6

arthas-spy

Arthas启动时,Arthas会把spyJar添加到目标应用的BootstrapClassLoader的搜索路径中,这样不管是Arthas还是目标应用,他们加载的都是同一个SpyAPI

  1. 解析参数

    Bootstrap bootstrap = new Bootstrap();
    CLI cli = CLIConfigurator.define(Bootstrap.class);
    CommandLine commandLine = cli.parse(Arrays.asList(args));
    CLIConfigurator.inject(commandLine, bootstrap);
    
    1
    2
    3
    4
  2. 通过反向启动字符客户端

    URLClassLoader classLoader = new URLClassLoader(new URL[]{new File(arthasHomeDir, "arthas-client.jar").toURL().toURL()});
    Class<?> telnetConsoleClass = classLoader.loadClass("com.taobao.arthas.client.TelnetConsole");
    Method mainMethod = telnetConsoleClas.getMethod("main", String[].class);
    
    1
    2
    3
    # https://www.jianshu.com/p/0771646f3f25
上次更新: : 7 months ago