Menu

#107 100% coverage impossible in Java 6 with asserts

open
CORE (51)
5
2014-09-19
2009-04-14
Tim Freeman
No

Using emma-stable-2.1.5320-lib.zip and java version 1.6.0_0 on Ubuntu, I observe that it's impossible to get 100% coverage for the following code when asserts are enabled:

public class Bar {
public int baz (int x) {
int y = x + 7;
assert x == 3;
//if (x != 3) {
// throw new AssertionError();
//}
return y;
}
}

The problem becomes clear when I disassemble the generated code. "javap -c -classpath . Bar" prints some ordinary things but ends with this block:

static {};
Code:
0: ldc_w #5; //class Bar
3: invokevirtual #6; //Method java/lang/Class.desiredAssertionStatus:()Z
6: ifne 13
9: iconst_1
10: goto 14
13: iconst_0
14: putstatic #2; //Field $assertionsDisabled:Z
17: return

There is no way to execute location 9 and location 13 in one run of the JVM.

Assuming Java continues with this strategy of having per-class assertion flags with unreachable code in subsequent releases, Emma would ideally have an option to recognize the idiomatic call to desiredAssertionStatus with the two blocks with ifconst_1 and ifconst_0 and declare both sides to always be covered regardless of what really happened.

I am attaching a file bug.zip. If you put it in a directory, you can reproduce the problem with these steps:

$ unzip bug.zip
Archive: bug.zip
inflating: Bar.java
inflating: Foo.java
$ javac Foo.java Bar.java
$ java -ea -cp ../emma.jar emmarun -cp . Foo
EMMA: collecting runtime coverage data ...
EMMA: runtime controller started on port [47653]
10
Got a java.lang.AssertionError
EMMA: writing [txt] report to [/home/tim/briefcase-homelinux/projects/emma/test/coverage.txt] ...
$ java -version
java version "1.6.0_0"
IcedTea6 1.3.1 (6b12-0ubuntu6.4) Runtime Environment (build 1.6.0_0-b12)
OpenJDK Server VM (build 1.6.0_0-b12, mixed mode)

Then look in coverage.txt to see the non-100% coverage.

Discussion

  • Tim Freeman

    Tim Freeman - 2009-04-14

    Zip file with source code for reproducing the bug

     
  • Tim Freeman

    Tim Freeman - 2009-04-14

    Just now I downloaded Java 1.6.0_13 and was able to reproduce the problem. This is the latest published update to Java 1.6 as I write this on April 14, 2009.

    It occurs to me that the unreachable code is pointless. There's no need to branch on a boolean and then push 1 or 0 and then store that somewhere. Instead, they could just store the boolean there directly. So there is hope that Sun will stop generating the pointless code. Apparently they have not yet done so.

     

Log in to post a comment.