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