-
Bug
-
Resolution: Fixed
-
P4
-
6, 7, 8, 9
-
b08
-
generic
-
generic
FULL PRODUCT VERSION :
java version "1.8.0_102"
Java(TM) SE Runtime Environment (build 1.8.0_102-b14)
Java HotSpot(TM) 64-Bit Server VM (build 25.102-b14, mixed mode)
A DESCRIPTION OF THE PROBLEM :
Compiler misses to include entry in LineNumberTable for break statement that jumps out of try-finally, however adds such entry in other cases. Not counting inconsistency between cases, for debugger this means that breakpoint cannot be set on a line with such break statement.
Seems that this is not a regression since the same behavior is observed with javac 1.6.0_65 and 1.7.0_80.
Background information: I'm one of developers of the JaCoCo code coverage tool. This tool relies on line number debug information within class files to provide code coverage highlighting. The defect reported here was uncovered during addition of tests into our regression test suite.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Compile the provided source file with javac 1.8.0_131
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
The compiled class files has a LineNumberTable entry for the break statement in line 7.
ACTUAL -
There is no LineNumberTable entry for the break statement in line 7, however there is entry for the break statement in line 19 - see javap output below:
void nok();
descriptor: ()V
flags:
Code:
stack=2, locals=3, args_size=1
0: iconst_0
1: istore_1
2: iload_1
3: iconst_1
4: if_icmpge 37
7: invokestatic #2 // Method condition:()Z
10: ifeq 19
13: invokestatic #3 // Method nop:()V
16: goto 37
19: invokestatic #3 // Method nop:()V
22: goto 31
25: astore_2
26: invokestatic #3 // Method nop:()V
29: aload_2
30: athrow
31: iinc 1, 1
34: goto 2
37: return
Exception table:
from to target type
7 13 25 any
LineNumberTable:
line 4: 0
line 6: 7
line 10: 13
line 11: 22
line 10: 25
line 4: 31
line 13: 37
void ok();
descriptor: ()V
flags:
Code:
stack=2, locals=3, args_size=1
0: iconst_0
1: istore_1
2: iload_1
3: iconst_1
4: if_icmpge 22
7: invokestatic #2 // Method condition:()Z
10: ifeq 16
13: goto 22
16: iinc 1, 1
19: goto 2
22: invokestatic #3 // Method nop:()V
25: goto 34
28: astore_2
29: invokestatic #3 // Method nop:()V
32: aload_2
33: athrow
34: return
Exception table:
from to target type
0 22 28 any
LineNumberTable:
line 17: 0
line 18: 7
line 19: 13
line 17: 16
line 23: 22
line 24: 25
line 23: 28
line 25: 34
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
class Example {
void nok() {
for (int i = 0; i < 1; i++) {
try {
if (condition()) {
break; // NOK
}
} finally {
nop();
}
}
}
void ok() {
try {
for (int i = 0; i < 1; i++) {
if (condition()) {
break; // OK
}
}
} finally {
nop();
}
}
static boolean condition() {
return false;
}
static void nop() {
}
}
---------- END SOURCE ----------
java version "1.8.0_102"
Java(TM) SE Runtime Environment (build 1.8.0_102-b14)
Java HotSpot(TM) 64-Bit Server VM (build 25.102-b14, mixed mode)
A DESCRIPTION OF THE PROBLEM :
Compiler misses to include entry in LineNumberTable for break statement that jumps out of try-finally, however adds such entry in other cases. Not counting inconsistency between cases, for debugger this means that breakpoint cannot be set on a line with such break statement.
Seems that this is not a regression since the same behavior is observed with javac 1.6.0_65 and 1.7.0_80.
Background information: I'm one of developers of the JaCoCo code coverage tool. This tool relies on line number debug information within class files to provide code coverage highlighting. The defect reported here was uncovered during addition of tests into our regression test suite.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Compile the provided source file with javac 1.8.0_131
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
The compiled class files has a LineNumberTable entry for the break statement in line 7.
ACTUAL -
There is no LineNumberTable entry for the break statement in line 7, however there is entry for the break statement in line 19 - see javap output below:
void nok();
descriptor: ()V
flags:
Code:
stack=2, locals=3, args_size=1
0: iconst_0
1: istore_1
2: iload_1
3: iconst_1
4: if_icmpge 37
7: invokestatic #2 // Method condition:()Z
10: ifeq 19
13: invokestatic #3 // Method nop:()V
16: goto 37
19: invokestatic #3 // Method nop:()V
22: goto 31
25: astore_2
26: invokestatic #3 // Method nop:()V
29: aload_2
30: athrow
31: iinc 1, 1
34: goto 2
37: return
Exception table:
from to target type
7 13 25 any
LineNumberTable:
line 4: 0
line 6: 7
line 10: 13
line 11: 22
line 10: 25
line 4: 31
line 13: 37
void ok();
descriptor: ()V
flags:
Code:
stack=2, locals=3, args_size=1
0: iconst_0
1: istore_1
2: iload_1
3: iconst_1
4: if_icmpge 22
7: invokestatic #2 // Method condition:()Z
10: ifeq 16
13: goto 22
16: iinc 1, 1
19: goto 2
22: invokestatic #3 // Method nop:()V
25: goto 34
28: astore_2
29: invokestatic #3 // Method nop:()V
32: aload_2
33: athrow
34: return
Exception table:
from to target type
0 22 28 any
LineNumberTable:
line 17: 0
line 18: 7
line 19: 13
line 17: 16
line 23: 22
line 24: 25
line 23: 28
line 25: 34
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
class Example {
void nok() {
for (int i = 0; i < 1; i++) {
try {
if (condition()) {
break; // NOK
}
} finally {
nop();
}
}
}
void ok() {
try {
for (int i = 0; i < 1; i++) {
if (condition()) {
break; // OK
}
}
} finally {
nop();
}
}
static boolean condition() {
return false;
}
static void nop() {
}
}
---------- END SOURCE ----------