zorka源码解读之Instrument实现原理

时间:2023-01-08 21:30:24

主要用到三方面技术:

  1. beanshell来实现可扩展:告诉zorkaAgent插桩的具体需求,包括插桩的方法和值、插桩的时机、插桩追踪记录方式等。
  2. Instrument来通过代理的方式访问JVM,实现在类加载的时候访问类字节码。
  3. ASM字节码操纵框架,用于实现真正底层的类字节码的修改。

一、beanshell实现插桩具体需求(bsh如何将要插桩的内容告诉代理程序的?)
给classTransformer添加SpyDefinition的实例,SpyDefinition里面定义了各种插桩行为,这些行为传递到底层主要封装到SpyProbe和SpyProcessor中了。SpyProbe的实例集合和SpyProcessor的实例集合都是SpyDefinition的属性。

zorka源码解读之Instrument实现原理

zorka源码解读之Instrument实现原理

二、Instrument插桩过程

1、AgentMain.premain方法的执行
在JVM执行ClassLoader.defineClass之后,应用程序main方法执行之前,premain方法开始执行。
premain方法中主要执行两个任务:
1) AgentInstance.start()加载beanshell,给beanshell注册zorkaAgent中的lib,并执行bsh。bsh的执行,主要是往SpyClassTransformer(start的时候实例化transformer)中添加SpyDefinition。
SpyDefinition中包含了插桩的所有信息。
2)给instrumentation添加transformer。

2、classTransformer.transform方法的执行
每装载一个类,transformer的transform方法就会执行一次,看看是否需要转换。transform函数的最后,若返回null值,表示不需要进行类字节码的转化,否则返回转换后的class字节数组。
transform中核心的代码是调用ASM的字节码访问技术:

ClassReader cr = new ClassReader(cbf);//cbf是类字节码的字节数组
ClassWriter cw = new ClassWriter(cr, cbf[7] > (byte)0x32 ? ClassWriter.COMPUTE_FRAMES : 0);
ClassVisitor scv = createVisitor(classLoader, clazzName, found, tracer, cw);//found就是SpyDefinition的集合
cr.accept(scv, 0);//给classReader传递字节码访问者,这个方法里面开始正式的字节码访问。
buf = cw.toByteArray();

1)accept中开始visitor(SpyClassVisitor)的各种visit方法的调用。比如visit(访问类声明)、visitSource、visitOuterClass、visitInnerClass、readMethod(读取方法,让指定visitor访问)、readField、visitAnnotaiton、visitTypeAnnotation、visitAttribute、visitEnd,这些方法按一定顺序被执行。在这里我们关注readMethod的调用。
2)readMethod调用spyClassVisitor的visitMethod方法。visitMethod解析SpyDefinition,根据SpyMatcher匹配目标方法,获取SpyContext上下文传递给下一个节点访问者。比如方法访问者SpyMethodVisitor。这个对象会返回到readMethod方法中继续执行访问。
3)SpyMethodVisitor中的visit方法会被调用。其中有visitAnnotation、visitCode、visitInsn、visitMaxs等。
4)上面的visit访问会调用emitProbes方法。该访问会根据SpyContext中定义的SpyDefinition,SpyDefinition里面的probe进行插桩。

private int emitProbes(int stage, SpyContext ctx)

5)emitProbes方法遍历SpyContext里面的probe,调用probe.emit方法进行插桩。

zorka源码解读之Instrument实现原理的更多相关文章

  1. Vue源码--解读vue响应式原理

    原文链接:https://geniuspeng.github.io/2018/01/05/vue-reactivity/ Vue的官方说明里有深入响应式原理这一节.在此官方也提到过: 当你把一个普通的 ...

  2. React 源码解读参考,理解原理。

    Rubix - ReactJS Powered Admin Template 文档:   http://rubix-docs.sketchpixy.com/ ===================== ...

  3. zorka源码解读之通过beanshell进行插桩的流程

    zorka中插桩流程概述 1.在SpyDefinition中配置插桩属性,将SpyDefinition实例提交给插桩引擎.2.SpyDefinition实例中包含了插桩探针probes,probe插入 ...

  4. zorka源码解读之tracer内部实现

    核心类: ZorkaAsyncThread.java protected BlockingQueue<T> submitQueue; /** * Processes single item ...

  5. zorka源码解读之Beanshell与zorka的交互实现

    一.beanshell基础知识从应用程序中调用BeanShell创建一个BeanShell的解释器(interpreter)用eval()和source()命令可以对一个字符串求值和运行一个脚本文件使 ...

  6. Webpack探索【16】--- 懒加载构建原理详解(模块如何被组建&amp&semi;如何加载)&amp&semi;源码解读

    本文主要说明Webpack懒加载构建和加载的原理,对构建后的源码进行分析. 一 说明 本文以一个简单的示例,通过对构建好的bundle.js源码进行分析,说明Webpack懒加载构建原理. 本文使用的 ...

  7. Webpack探索【15】--- 基础构建原理详解(模块如何被组建&amp&semi;如何加载)&amp&semi;源码解读

    本文主要说明Webpack模块构建和加载的原理,对构建后的源码进行分析. 一 说明 本文以一个简单的示例,通过对构建好的bundle.js源码进行分析,说明Webpack的基础构建原理. 本文使用的W ...

  8. 2,MapReduce原理及源码解读

    MapReduce原理及源码解读 目录 MapReduce原理及源码解读 一.分片 灵魂拷问:为什么要分片? 1.1 对谁分片 1.2 长度是否为0 1.3 是否可以分片 1.4 分片的大小 1.5 ...

  9. 第二十三课:jQuery&period;event&period;add的原理以及源码解读

    本课主要来讲解一下jQuery是如何实现它的事件系统的. 我们先来看一个问题: 如果有一个表格有100个tr元素,每个都要绑定mouseover/mouseout事件,改成事件代理的方式,可以节省99 ...

随机推荐

  1. 帆软报表FineReport中数据连接之Jboss配置JNDI连接

    使用sqlsever 2000数据库数据源来做实例讲解,帆软报表FineReport数据连接中Jboss配置JNDI大概的过程和WEBSPHERE以及WEBLOGIC基本相同,用JDBC连接数据库制作 ...

  2. 一次完整的HTTP请求流程

    HTTP通信机制是在一次完整的HTTP通信过程中,Web浏览器与Web服务器之间将完成下列7个步骤: 1. 建立TCP连接: 在HTTP工作开始之前,Web浏览器首先要通过网络与Web服务器建立连接, ...

  3. &lbrack;iOS UI设计笔记整理汇总&rsqb;

    8.UIsearchbar放到Navigationbar 上(意思是建个View作为titleview) //此处调用的是第三方封装的SearchBar,也可以自定义. self.searchBarW ...

  4. 排颜色问题——数组 leetcode lintcode

    问题描写叙述: 给一个数组,而且数组里面元素的值仅仅可能是0,1,2,然后如今把这个数组排序. 第二种表述: 现有n个红白蓝三种不同颜色的小球,乱序排列在一起,请通过两两交换随意两个球,使得从左至右, ...

  5. 【安德鲁斯】基于脚本的数据库&amp&semi;quot&semi;增量更新&amp&semi;quot&semi;&comma;如果不改变,每次更新java代码、&excl;

    思维: 1.当然,它是基于SQLiteOpenHelper.onCreate(第一个呼叫建立).onUpdate(当所谓的升级计划) 2.用"脚本"(脚本制作详细方法问度娘)做数据 ...

  6. C&num;使用IHttpModule接口修改http输出的方法浅谈

    一.但你每次请求浏览一个页面,比如Login.aspx的时候,都会执行配置文件中system.webserver内的model这个节点的东西(这个是属于遍历的逻辑执行,会将model这个节点的东西全部 ...

  7. http content-type accept的区别

    1.Accept属于请求头, Content-Type属于实体头. Http报头分为通用报头,请求报头,响应报头和实体报头. 请求方的http报头结构:通用报头|请求报头|实体报头 响应方的http报 ...

  8. SpringCloud教程 &vert; 第四篇&colon;断路器(Hystrix)

    在微服务架构中,根据业务来拆分成一个个的服务,服务与服务之间可以相互调用(RPC),在Spring Cloud可以用RestTemplate+Ribbon和Feign来调用.为了保证其高可用,单个服务 ...

  9. web移动端类型检测

    移动端检测 插件通用下载: https://www.bootcdn.cn/ 根据一个库 device.js 下载地址 传送 api 传送 和 传送 常用检测类型 device.ipad() 返回一个布 ...

  10. BZOJ3730震波——动态点分治&plus;线段树&lpar;点分树套线段树&rpar;

    题目描述 在一片土地上有N个城市,通过N-1条无向边互相连接,形成一棵树的结构,相邻两个城市的距离为1,其中第i个城市的价值为value[i].不幸的是,这片土地常常发生地震,并且随着时代的发展,城市 ...