JVM-Sandbox

JVM-Sandbox

# 下载最新版本的JVM-SANDBOX
wget http://ompc.oss-cn-hangzhou.aliyuncs.com/jvm-sandbox/release/sandbox-stable-bin.zip

# 解压
unzip sandbox-stable-bin.zip

解决sandox的运行问题,使用函数代替sandbox.sh

sandbox ()
{
    cd /Users/seveniruby/temp/java_2/jvm-sandbox/sandbox/bin/;
    ./sandbox.sh "$@";
    cd $OLDPWD
}

下载代码,使用IDEA打开

git clone https://github.com/alibaba/jvm-sandbox.git

代码trace

cp example/sandbox-debug-module.jar ~/.sandbox-module/
sandbox -p 23220 -F
sandbox -p 23220 -d 'debug-trace/trace?class=java.io.PrintStream&method=println'

应用

Bug Fix

代码Trace

        final EventWatcher watcher = new EventWatchBuilder(moduleEventWatcher)
                .onClass(cnPattern).includeSubClasses()
                .onBehavior(mnPattern)
                .onWatching()
                .withCall().withLine()
-------
--------
-------
                    @Override
                    protected void beforeLine(Advice advice, int lineNum) {
//                        super.beforeLine(advice, lineNum);
                        String result=advice.getTarget().getClass().getCanonicalName()+": @"
                                +lineNum+": "
                                + advice.getBehavior().getName();
                        printer.println(result);
                    }

使用

sandbox -p $pid -d 'debug-trace/trace?class=com.taobao.demo.Clock&method=*'

性能度量

故障注入

 sandbox -p $pid -d 'debug-ralph/wreck?class=com.taobao.demo.Clock&method=report&type=IOException'

更改参数与返回值

    /**
     * 改变方法入参
     *
     * @param index       方法入参编号(从0开始)
     * @param changeValue 改变的值
     * @return this
     * @since {@code sandbox-api:1.0.10}
     */
    public BeforeEvent changeParameter(final int index,
                                       final Object changeValue) {
        argumentArray[index] = changeValue;
        return this;
    }

作业地址

作业2

启动你的某个Java进程, 注入一个空指针异常,做个演练。不要使用clock。把sandbox的输出贴过来。

com.taobao.demo.Clock.report will be wreck by exception: IOException on com.taobao.demo.Clock.main()
1 个赞

占楼。。。。。。。。

常用加俩参数 jps -ml

sandbox -p 进程ID。这命令,在操作系统层面是什么原理。一个进程怎么能去干扰另一个进程的执行?还是说,sandbox利用了jvm里面的机制,通过操作目标进程的jvm虚拟机来达到目的的?

1、sandbox能从整个代码工程角度分析吗,看到大部分是需要传类和方法?
2、麻烦老师写下统计黑盒测试代码覆盖率这块的步骤,怎么将sandbox和sonarqube结合使用?

在工作中基本上是黑盒测试,很少考虑故障注入,是需要去看源代码后,再去每个抛出异常的地方都故障注入吗?

如何与sonar结合

  • 编写模块,记录beforeLine
  • class method line file 保存到log
  • testcase -> trace record
  • trace log -> soanr的自定义覆盖率文件
  • soanr-scanner 上传分析结果
<coverage version="1">
  <file path="src/main/java/com/acme/basic/HelloWorld.java">
    <lineToCover lineNumber="13" covered="true"/>
    <lineToCover lineNumber="8" covered="false"/>
  </file>
  <file path="xources/hello/WithConditions.xoo">
    <lineToCover lineNumber="3" covered="true" branchesToCover="2" coveredBranches="1"/>
  </file>
</coverage

不是的,故障注入是可以完全自动化的。

  • trace所有可能有异常的函数。io读写api、network存取api
  • 注入故障

注入故障要有业务含义。

systemtap可以注入更底层的故障,运维喜欢用的方案。

问个比较小白的问题. 精准化测试的意义是什么?对于很多中小型互联网企业似乎没有太大的必要性?

想知道根据线上的流量生成自动化用例并去做diff,diff的是哪些内容呢?

##作业1
https://github.com/wangpeng2020/sandybox-module

##作业2

作业1

https://github.com/zwp369/jvm-sandbox-bugfix

作业2

未解决问题

  1. 在错误的情况下原样执行了思寒老师的解决sandox的运行问题,使用函数代替sandbox.sh 后,再重新执行正确的shell脚本后,运行sandbox 命令总是需要执行2次才会运行,怎么解决呢?

  2. 自己写的一个类,在抛出IO异常的时候,不知道故障注入是对try{}catch{} 起作用还是throws ? 最终实践貌似是有try{}catch{}起的作用,不确定自己是否理解正确。

实操遇到几个问题(已解决):
1、shell中直接java com.taobao.demo.Clock 启动的进程

ps -ef|grep Clock
XXXX 31624 28335  0 14:28 pts/3    00:00:00 java com.taobao.demo.Clock

31624 进程不能attach。报错如下:

 sandbox -p 31624
com.sun.tools.attach.AttachNotSupportedException: Unable to open socket file: target process not responding or HotSpot VM not loaded
	at sun.tools.attach.LinuxVirtualMachine.<init>(LinuxVirtualMachine.java:106)
	at sun.tools.attach.LinuxAttachProvider.attachVirtualMachine(LinuxAttachProvider.java:63)
	at com.sun.tools.attach.VirtualMachine.attach(VirtualMachine.java:208)
	at com.alibaba.jvm.sandbox.core.CoreLauncher.attachAgent(CoreLauncher.java:59)
	at com.alibaba.jvm.sandbox.core.CoreLauncher.<init>(CoreLauncher.java:20)
	at com.alibaba.jvm.sandbox.core.CoreLauncher.main(CoreLauncher.java:43)
sandbox load jvm failed : Unable to open socket file: target process not responding or HotSpot VM not loaded
attach JVM 31624 fail.

2、把Clock的jar包打出来后启动,找到对应pid。报错同上。加-P 端口号参数错误一样
尝试 sandbox -p pid 的时候,运行的Clock会打印如下日志

java.lang.IllegalStateException: STATE ERROR!
	at com.taobao.demo.Clock.checkState(Clock.java:13)
	at com.taobao.demo.Clock.report(Clock.java:31)
	at com.taobao.demo.Clock.loopReport(Clock.java:41)
	at com.taobao.demo.Clock.main(Clock.java:50)
java.lang.IllegalStateException: STATE ERROR!
2020-03-29 17:32:45
Full thread dump Java HotSpot(TM) 64-Bit Server VM (25.101-b13 mixed mode):

"Service Thread" #8 daemon prio=9 os_prio=0 tid=0x00007f9cec1a2800 nid=0x1a0c runnable [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"C1 CompilerThread2" #7 daemon prio=9 os_prio=0 tid=0x00007f9cec185800 nid=0x1a0b waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"C2 CompilerThread1" #6 daemon prio=9 os_prio=0 tid=0x00007f9cec184000 nid=0x1a0a waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"C2 CompilerThread0" #5 daemon prio=9 os_prio=0 tid=0x00007f9cec181000 nid=0x1a09 waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"Signal Dispatcher" #4 daemon prio=9 os_prio=0 tid=0x00007f9cec17f800 nid=0x1a08 waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"Finalizer" #3 daemon prio=8 os_prio=0 tid=0x00007f9cec14b800 nid=0x1a05 in Object.wait() [0x00007f9cd5f1d000]
   java.lang.Thread.State: WAITING (on object monitor)
	at java.lang.Object.wait(Native Method)
	- waiting on <0x000000076cb08ee0> (a java.lang.ref.ReferenceQueue$Lock)
	at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:143)
	- locked <0x000000076cb08ee0> (a java.lang.ref.ReferenceQueue$Lock)
	at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:164)
	at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:209)

"Reference Handler" #2 daemon prio=10 os_prio=0 tid=0x00007f9cec147000 nid=0x1a04 in Object.wait() [0x00007f9cd601e000]
   java.lang.Thread.State: WAITING (on object monitor)
	at java.lang.Object.wait(Native Method)
	- waiting on <0x000000076cb06b50> (a java.lang.ref.Reference$Lock)
	at java.lang.Object.wait(Object.java:502)
	at java.lang.ref.Reference.tryHandlePending(Reference.java:191)
	- locked <0x000000076cb06b50> (a java.lang.ref.Reference$Lock)
	at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:153)

"main" #1 prio=5 os_prio=0 tid=0x00007f9cec00a000 nid=0x19fd waiting on condition [0x00007f9cf3845000]
   java.lang.Thread.State: TIMED_WAITING (sleeping)
	at java.lang.Thread.sleep(Native Method)
	at com.taobao.demo.Clock.loopReport(Clock.java:45)
	at com.taobao.demo.Clock.main(Clock.java:50)

"VM Thread" os_prio=0 tid=0x00007f9cec13f800 nid=0x1a03 runnable 

"GC task thread#0 (ParallelGC)" os_prio=0 tid=0x00007f9cec020000 nid=0x19fe runnable 

"GC task thread#1 (ParallelGC)" os_prio=0 tid=0x00007f9cec021800 nid=0x19ff runnable 

"GC task thread#2 (ParallelGC)" os_prio=0 tid=0x00007f9cec023800 nid=0x1a00 runnable 

"GC task thread#3 (ParallelGC)" os_prio=0 tid=0x00007f9cec025000 nid=0x1a01 runnable 

"VM Periodic Task Thread" os_prio=0 tid=0x00007f9cec1a6000 nid=0x1a0d waiting on condition 

JNI global references: 6
java.lang.IllegalStateException: STATE ERROR!
	at com.taobao.demo.Clock.checkState(Clock.java:13)
	at com.taobao.demo.Clock.report(Clock.java:31)
	at com.taobao.demo.Clock.loopReport(Clock.java:41)
	at com.taobao.demo.Clock.main(Clock.java:50)
java.lang.IllegalStateException: STATE ERROR!

以上环境ubuntu,还换过jdk没有解决,都是普通账户操作。换到centos7上面就没有这些问题。


这个问题是jdk的bug,解决办法。启动命令中增加jvm参数

java -XX:+StartAttachListener -jar .....

作业1:

作业2

sandbox -p 17285 -d 'debug-ralph/wreck?class=java.io.PrintStream&method=println&type=NullPointException'

执行注入NullpointerException


注入完成后的结果

作业一
https://github.com/ZhzhIn/testjvmsandbox.git
作业二

作业一:
https://github.com/xuzhenzhen/jvm-sandbox.git

作业1:
https://github.com/xinac0421/jvm-sandbox-clock
image

作业2:

作业一:
https://github.com/chongchong01/sandbox-module-demo/blob/master/src/main/java/com/sandbox/modules/CallStackTimeConsumeModule.java

作业二:

碰到的问题:
1.执行 sandbox -p $pid -l R F等命令的时候,有时回车没反应,卡住了,看日志也没报错.