jvm-sandbox对运行中的java执行文件做插桩,故障注入
jvm-sandbox github地址:
https://github.com/alibaba/jvm-sandbox/wiki/INSTALL
jvm-sandbox是java执行文件的插桩工具,可以对运行中的java执行文件进行插桩,修改或记录运行的数据。
原理参考github的原理图,根据JVMTI,对jvm进程进行修改。
步骤:
1.运行java文件
这里写了一个除0异常
public class MathMethod { //省略getter setter... public Integer testException() throws ArithmeticException{ return x/y; }
public class TestJvmSandbox {
public static void main(String[] args) {
MathMethod mm = new MathMethod(100, 0);
while (true) {
System.out.println(mm.add());
System.out.println(mm.millace());
System.out.println(mm.testException());
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("byebye");
}
}
}
2.安装jvm-sandbox
wget http://ompc.oss-cn-hangzhou.aliyuncs.com/jvm-sandbox/release/sandbox-stable-bin.zip unzip sandbox-stable-bin.zip
3.编写jvm-sandbox执行jar包
{ new EventWatchBuilder(moduleEventWatcher) .onClass("com.patech.MathMethod") .onBehavior("repairMathException") .onWatch(new AdviceListener() { /** * 拦截{@code com.patech.TestJvmSandbox#testException()}方法,当这个方法抛出异常时将会被 * AdviceListener#afterThrowing()所拦截 */ @Override protected void afterThrowing(Advice advice) throws Throwable { // 在此,你可以通过ProcessController来改变原有方法的执行流程 // 这里的代码意义是:改变原方法抛出异常的行为,变更为立即返回;void返回值用null表示 ProcessController.returnImmediately(null); } }); }
jar包cp到sandbox-module目录下
4.将sandbox执行jar包挂载到运行中的java进程中
查看java进程的jvm中的进程编号
jps -ml
#找到要插桩的jar包的pid
pid=[选择插桩的PID]
在sandbox中挂载jar包
./sandbox.sh -p $pid
./sandbox.sh -p $pid -l
#如果jar包挂载没有成功,-F刷新一下module的包,或者-S shutdown -R 重启
执行jar包的插桩命令
./sandbox.sh -p $pid -d "broken-math-repair/repairMathException"
5.观察问题解决的情况
6.故障注入
./sandbox.sh -p $pid -d 'debug-ralph/wreck?class=com.patech.MathMethod&method=testOutput&type=NullPointException'
注入结果