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'
注入結果

