美文网首页
编译插桩介绍

编译插桩介绍

作者: HarryChen | 来源:发表于2021-05-26 15:34 被阅读0次

概念

编译插桩就是在代码编译期间修改修改已有的代码或者生成新的代码。
编译插桩技术从对代码修改的时机上来说可以分为两种:
Java 文件:在编译最开始的时候介入,动态生成 Java 文件,之后编译器将生成的 Java 文件编译成 class 文件,像 ButterKnife、Dagger 都是通过 这种方式生成代码的。对应的技术主要是APT(Annotation Process Tools

字节码文件:在生成 class 文件后介入,直接修改 class文件的字节码,达到修改代码的目的。常用的字节码编程框架有AspectJJavassistASM

bytecodeprogress.png

什么是字节码?

Java 字节码是Java虚拟机执行的一种指令格式。Java源文件经Java编译器后得到Java字节码(.class)文件。Java字节码(.class)文件可以看作是Java虚拟机的可执行文件。这些字节码(.class)文件拥有足够的元数据来解析类中的所有元素:类名称、方法、属性以及 Java 字节码(指令)

如何查看字节码

这里拿AndroidStudio举例,所有基于IDEA的IDE应该都一样。
在Settings -> Tools中添加External Tools,输入Name和下面三要素,保存即可

  • $JDKPath$\bin\javap
  • -c -verbose $FileClass$
  • $OutputPath$
showbytesetting.png
每次生成字节码之前记得先build/rebuild一下工程,不然会失败
showbytecode.png

简单分析下字节码构成

byte1.png byte2.png byte3.png
  • kotlin文件查看方式
showkotlin.png

Android字节码编程

在安卓中,编译过程是由gradle task来执行的,Gradle1.5以后提供了transform-api可以在代码转化为.class文件之后再打包成dex文件之前对它进行处理,所以我们可以自定义transform,在appcompileDebugJavaWithJavac这个gradle task之后就会走我们自定义的transform。

使用场景

  • 代码生成。除了 Dagger、ButterKnife 这些常用的注解生成框架,Protocol Buffers、数据库 ORM 框架也都会在编译过程生成代码。代码生成隔离了复杂的内部实现,让开发更加简单高效,而且也减少了手工重复的劳动量,降低了出错的可能性。
  • 代码监控。除了网络监控和耗电监控,我们可以利用编译插桩技术实现各种各样的性能监控。为什么不直接在源码中实现监控功能呢?首先我们不一定有第三方 SDK 的源码,其次某些调用点可能会非常分散,例如想监控代码中所有 new Thread() 调用,通过源码的方式并不那么容易实现。
  • 代码修改。我们在这个场景拥有无限的发挥空间,例如某些第三方 SDK 库没有源码,我们可以给它内部的一个崩溃函数增加 try catch,或者说替换它的图片库等。我们也可以通过代码修改实现无痕埋点。
  • 代码分析。上一期我讲到持续集成,里面的自定义代码检查就可以使用编译插桩技术实现。例如检查代码中的 new Thread() 调用、检查代码中的一些敏感权限使用等。事实上,Findbugs 这些第三方的代码检查工具也同样使用的是编译插桩技术实现。

插桩实践

Javassist+gradle transform+annotation 实现方法耗时统计

相关文章

  • 编译插桩介绍

    概念 编译插桩就是在代码编译期间修改修改已有的代码或者生成新的代码。编译插桩技术从对代码修改的时机上来说可以分为两...

  • 编译插桩操作字节码(ASM版本)

    来源:编译插桩操纵字节码,实现不可能完成的任务 编译插桩 编译插桩就是在代码编译期间修改已有的代码或者生成新代码。...

  • 字节码插桩极简入门

    不写废话,帮助你快速理解应对面试 目录 什么是编译插桩插桩的应用场景插桩的工具 什么是编译插桩 用通俗的话来讲,插...

  • 编译插桩

    编译插桩是指在代码编译期间修改或新增代码 可以两个地方进行编译插桩 1、java编译为class时 APT、And...

  • 吹爆系列:Android 插桩之美,全面掌握!

    一、插桩 插桩是什么?你在开发中有用过插桩的技术吗? 所谓的插桩就是在代码编译期间修改已有的代码或者生成新代码。 ...

  • libfuzzer实战——libwebp coverage插桩

    libfuzzer实战——libwebp coverage插桩 afl,libfuzzer,hongg这类编译时插...

  • 说说编译插桩

    1.什么是编译插桩? 顾名思义,所谓的编译插桩就是在代码编译期间修改已有的代码或者生成新代码。 如图,这是Java...

  • 注解 - 插桩,编译后处理筛选

    什么是插桩? 插桩就是将一段代码插入或者替换原本的代码。字节码插桩顾名思义就是在我们编写的源码编译成字节码(Cla...

  • 注解的使用(二):插桩,编译后处理筛选

    什么是插桩? 插桩就是将一段代码插入或者替换原本的代码。字节码插桩顾名思义就是在我们编写的源码编译成字节码(Cla...

  • Mac使用gcov、lcov进行覆盖率测试

    本文目的: 简单介绍所使用的工具 示范一遍覆盖率流程 得到代码文件→进行编译并插桩→跑程序→运行gcov、lcov...

网友评论

      本文标题:编译插桩介绍

      本文链接:https://www.haomeiwen.com/subject/bsvksltx.html