-
Bug
-
Resolution: Fixed
-
P4
-
cdc-hi_1.0, cdc_1.0.1, 1.3.0
-
mantis
-
generic, x86
-
generic, solaris_7, windows_2000
Bug was (see original bug report which follows):
JPDA: LocalVariable.isVisible() returns wrong value when local var uninitialized
Cause of problem determined to be that new javac compiler generates
incorrect LocalVariableTable attributes for variables which do not
need to be initialized. Specifically, the generated table includes
pc values where the variable does not have value.
The example below shows first the result of compiling with the old
compiler then the new. After this is the original report.
% cat -n Test.java
1 class Test
2 {
3 public static void main(String[] args)
4 {
5 int i = 1;
6 String command;
7 if (i == 0) {
8 command = "0";
9 } else if (i == 1) {
10 command = "1";
11 } else {
12 command = null;
13 }
14 }
15 }
% /usr/local/java/jdk1.2.2-solaris/bin/javac -g Test.java
% javap -l -c Test
Compiled from Test.java
class Test extends java.lang.Object {
Test();
public static void main(java.lang.String []);
Method Test()
0 aload_0
1 invokenonvirtual #5 <Method java.lang.Object.<init>()V>
4 return
Method void main(java.lang.String [])
0 iconst_1
1 istore_1
2 iload_1
3 ifne 12
6 ldc #1 <String "0">
8 astore_2
9 goto 25
12 iload_1
13 iconst_1
14 if_icmpne 23
17 ldc #2 <String "1">
19 astore_2
20 goto 25
23 aconst_null
24 astore_2
25 return
Line numbers for method Test()
line 1: 0
Line numbers for method void main(java.lang.String [])
line 5: 0
line 7: 2
line 8: 6
line 7: 9
line 9: 12
line 10: 17
line 9: 20
line 12: 23
line 3: 25
Local variables for method Test()
Test this pc=0, length=5, slot=0
Local variables for method void main(java.lang.String [])
java.lang.String args[] pc=0, length=26, slot=0
int i pc=2, length=24, slot=1
java.lang.String command pc=9, length=3, slot=2
java.lang.String command pc=20, length=3, slot=2
java.lang.String command pc=25, length=1, slot=2
}
Note that the local variable table above correctly separates
the three areas where the variable is valid. Now from 1.3 --
% /usr/local/java/jdk1.3.0-solaris/solaris/bin/javac -g Test.java
% javap -l -c Test
Compiled from Test.java
class Test extends java.lang.Object {
Test();
public static void main(java.lang.String []);
Method Test()
0 aload_0
1 invokenonvirtual #1 <Method java.lang.Object.<init>()V>
4 return
Method void main(java.lang.String [])
0 iconst_1
1 istore_1
2 iload_1
3 ifne 12
6 ldc #2 <String "0">
8 astore_2
9 goto 25
12 iload_1
13 iconst_1
14 if_icmpne 23
17 ldc #3 <String "1">
19 astore_2
20 goto 25
23 aconst_null
24 astore_2
25 return
Line numbers for method Test()
line 1: 0
Line numbers for method void main(java.lang.String [])
line 5: 0
line 7: 2
line 8: 6
line 9: 12
line 10: 17
line 12: 23
line 14: 25
Local variables for method Test()
Test this pc=0, length=5, slot=0
Local variables for method void main(java.lang.String [])
java.lang.String args[] pc=0, length=26, slot=0
int i pc=2, length=23, slot=1
java.lang.String command pc=9, length=16, slot=2
}
Here the area where it is supposed to have value spans areas
where it does not. See below to see what effect this has.
------ original report ----------
Name: rl16235 Date: 06/29/2000
java version "1.3.0"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.3.0-C)
Java HotSpot(TM) Client VM (build 1.3.0-C, mixed mode)
StackFrame.getValue() consistently throws a
com.sun.jdi.InconsistentDebugInfoException when getValue() is requested on a
LocalVariable that is currently uninitialized. Example code:
class Test
{
public static void main(String[] args)
{
int i = 1;
String command;
if (i == 0) { // A: set initial breakpoint here and then step
command = "0";
} else if (i == 1) { B: // when here, exception is thrown
command = "1";
} else {
command = null;
}
}
}
The example above compiles because the compiler has determined that the local
variable 'command' will always be initialized after executing the if-elseif-
else statements thus 'command' does not have to be explicitly assigned an
initial value unlike local variable 'i'. When we query the value for the yet
uninitialized local variable 'command' in our debugger, a
com.sun.jdi.InconsistentDebugInfoException gets thrown. The LocalVariable
object representing 'command' returns true when isVisible() at point B: which
is problem where the problem lies.
###@###.### 2000-06-29
Here are steps to reproduce with jdb.
sunni-104% java -version
java version "1.3.0"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.3.0-C)
Java HotSpot(TM) Client VM (build 1.3.0-C, interpreted mode)
sunni-105% jdb -tclassic Test
Initializing jdb...
> stop at Test:7
Deferring breakpoint Test:7.
It will be set after the class is loaded.
> run
run Test
VM Started: > Set deferred breakpoint Test:7
Breakpoint hit: thread="main", Test.main(), line=7, bci=2
7 if (i == 0) { // A: set initial breakpoint here and then step
main[1] step
Step completed: thread="main", Test.main(), line=9, bci=12
9 } else if (i == 1) { B: // when here, exception is thrown
main[1] step
Step completed: main[1] thread="main", Test.main(), line=10, bci=17
10 command = "1";
main[1] dump command
com.sun.jdi.InconsistentDebugInfoException
at com.sun.tools.jdi.JDWPException.toJDIException(JDWPException.java:46)
at com.sun.tools.jdi.StackFrameImpl.getValues(StackFrameImpl.java:230)
at com.sun.tools.jdi.StackFrameImpl.getValue(StackFrameImpl.java:188)
at com.sun.tools.example.debug.expr.LValue$LValueLocal.getValue(LValue.java:233)
at com.sun.tools.example.debug.expr.ExpressionParser.evaluate(ExpressionParser.java:54)
at com.sun.tools.example.debug.tty.Commands.evaluate(Commands.java:72)
at com.sun.tools.example.debug.tty.Commands.doPrint(Commands.java:1362)
at com.sun.tools.example.debug.tty.Commands$3.run(Commands.java:1395)
(Review ID: 106669)
======================================================================
JPDA: LocalVariable.isVisible() returns wrong value when local var uninitialized
Cause of problem determined to be that new javac compiler generates
incorrect LocalVariableTable attributes for variables which do not
need to be initialized. Specifically, the generated table includes
pc values where the variable does not have value.
The example below shows first the result of compiling with the old
compiler then the new. After this is the original report.
% cat -n Test.java
1 class Test
2 {
3 public static void main(String[] args)
4 {
5 int i = 1;
6 String command;
7 if (i == 0) {
8 command = "0";
9 } else if (i == 1) {
10 command = "1";
11 } else {
12 command = null;
13 }
14 }
15 }
% /usr/local/java/jdk1.2.2-solaris/bin/javac -g Test.java
% javap -l -c Test
Compiled from Test.java
class Test extends java.lang.Object {
Test();
public static void main(java.lang.String []);
Method Test()
0 aload_0
1 invokenonvirtual #5 <Method java.lang.Object.<init>()V>
4 return
Method void main(java.lang.String [])
0 iconst_1
1 istore_1
2 iload_1
3 ifne 12
6 ldc #1 <String "0">
8 astore_2
9 goto 25
12 iload_1
13 iconst_1
14 if_icmpne 23
17 ldc #2 <String "1">
19 astore_2
20 goto 25
23 aconst_null
24 astore_2
25 return
Line numbers for method Test()
line 1: 0
Line numbers for method void main(java.lang.String [])
line 5: 0
line 7: 2
line 8: 6
line 7: 9
line 9: 12
line 10: 17
line 9: 20
line 12: 23
line 3: 25
Local variables for method Test()
Test this pc=0, length=5, slot=0
Local variables for method void main(java.lang.String [])
java.lang.String args[] pc=0, length=26, slot=0
int i pc=2, length=24, slot=1
java.lang.String command pc=9, length=3, slot=2
java.lang.String command pc=20, length=3, slot=2
java.lang.String command pc=25, length=1, slot=2
}
Note that the local variable table above correctly separates
the three areas where the variable is valid. Now from 1.3 --
% /usr/local/java/jdk1.3.0-solaris/solaris/bin/javac -g Test.java
% javap -l -c Test
Compiled from Test.java
class Test extends java.lang.Object {
Test();
public static void main(java.lang.String []);
Method Test()
0 aload_0
1 invokenonvirtual #1 <Method java.lang.Object.<init>()V>
4 return
Method void main(java.lang.String [])
0 iconst_1
1 istore_1
2 iload_1
3 ifne 12
6 ldc #2 <String "0">
8 astore_2
9 goto 25
12 iload_1
13 iconst_1
14 if_icmpne 23
17 ldc #3 <String "1">
19 astore_2
20 goto 25
23 aconst_null
24 astore_2
25 return
Line numbers for method Test()
line 1: 0
Line numbers for method void main(java.lang.String [])
line 5: 0
line 7: 2
line 8: 6
line 9: 12
line 10: 17
line 12: 23
line 14: 25
Local variables for method Test()
Test this pc=0, length=5, slot=0
Local variables for method void main(java.lang.String [])
java.lang.String args[] pc=0, length=26, slot=0
int i pc=2, length=23, slot=1
java.lang.String command pc=9, length=16, slot=2
}
Here the area where it is supposed to have value spans areas
where it does not. See below to see what effect this has.
------ original report ----------
Name: rl16235 Date: 06/29/2000
java version "1.3.0"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.3.0-C)
Java HotSpot(TM) Client VM (build 1.3.0-C, mixed mode)
StackFrame.getValue() consistently throws a
com.sun.jdi.InconsistentDebugInfoException when getValue() is requested on a
LocalVariable that is currently uninitialized. Example code:
class Test
{
public static void main(String[] args)
{
int i = 1;
String command;
if (i == 0) { // A: set initial breakpoint here and then step
command = "0";
} else if (i == 1) { B: // when here, exception is thrown
command = "1";
} else {
command = null;
}
}
}
The example above compiles because the compiler has determined that the local
variable 'command' will always be initialized after executing the if-elseif-
else statements thus 'command' does not have to be explicitly assigned an
initial value unlike local variable 'i'. When we query the value for the yet
uninitialized local variable 'command' in our debugger, a
com.sun.jdi.InconsistentDebugInfoException gets thrown. The LocalVariable
object representing 'command' returns true when isVisible() at point B: which
is problem where the problem lies.
###@###.### 2000-06-29
Here are steps to reproduce with jdb.
sunni-104% java -version
java version "1.3.0"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.3.0-C)
Java HotSpot(TM) Client VM (build 1.3.0-C, interpreted mode)
sunni-105% jdb -tclassic Test
Initializing jdb...
> stop at Test:7
Deferring breakpoint Test:7.
It will be set after the class is loaded.
> run
run Test
VM Started: > Set deferred breakpoint Test:7
Breakpoint hit: thread="main", Test.main(), line=7, bci=2
7 if (i == 0) { // A: set initial breakpoint here and then step
main[1] step
Step completed: thread="main", Test.main(), line=9, bci=12
9 } else if (i == 1) { B: // when here, exception is thrown
main[1] step
Step completed: main[1] thread="main", Test.main(), line=10, bci=17
10 command = "1";
main[1] dump command
com.sun.jdi.InconsistentDebugInfoException
at com.sun.tools.jdi.JDWPException.toJDIException(JDWPException.java:46)
at com.sun.tools.jdi.StackFrameImpl.getValues(StackFrameImpl.java:230)
at com.sun.tools.jdi.StackFrameImpl.getValue(StackFrameImpl.java:188)
at com.sun.tools.example.debug.expr.LValue$LValueLocal.getValue(LValue.java:233)
at com.sun.tools.example.debug.expr.ExpressionParser.evaluate(ExpressionParser.java:54)
at com.sun.tools.example.debug.tty.Commands.evaluate(Commands.java:72)
at com.sun.tools.example.debug.tty.Commands.doPrint(Commands.java:1362)
at com.sun.tools.example.debug.tty.Commands$3.run(Commands.java:1395)
(Review ID: 106669)
======================================================================
- relates to
-
JDK-4486859 REGRESSION: bad local variable table for exception parameter of catch block
- Resolved