Vojta
Vojta

Reputation: 173

Java - don't see a variable in debug without initialiazation it before

Given the following method in Java in jdk6

public void test(){
Integer i;
try{
   i = 9;
} catch (Exception ex){
   //nothing
}
int something = 1; //Breakpoint here
}

When I stop at the break point I dont see a variable "i" on stack at all even though going step by step I see that is was assigned 9 in the try block.

public void test(){
Integer i = null;
try{
   i = 9;
} catch (Exception ex){
   //nothing
}
int something = 1; //Breakpoint here
}

Initializing the variable "i" to null I will see the i = 9 when I get to the breakpoint.

I am just wondering what happens under the hood. Does compiler not put i on the stack in the first case or does the cause stem from JVM behavior itself.

Upvotes: 4

Views: 62

Answers (1)

Jeffrey Bosboom
Jeffrey Bosboom

Reputation: 13663

I'm assuming that "I dont see a variable "i" on stack at all" in your question means you don't see it in the stack frame in your debugger. (As opposed to on the JVM operand stack, which is a bytecode-level notion. It wouldn't be on the operand stack either, but for a different reason.)

Here's javap (disassembles Java .class files) output for your method:

  public void test();
descriptor: ()V
flags: ACC_PUBLIC
Code:
  stack=1, locals=3, args_size=1
     0: bipush        9
     2: invokestatic  #8                  // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
     5: astore_1
     6: goto          10
     9: astore_2
    10: iconst_1
    11: istore_2
    12: return
  Exception table:
     from    to  target type
         0     6     9   Class java/lang/Exception
  LineNumberTable:
    line 27: 0
    line 30: 6
    line 28: 9
    line 31: 10
    line 32: 12
  LocalVariableTable:
    Start  Length  Slot  Name   Signature
       10       0     2    ex   Ljava/lang/Exception;
        0      13     0  this   LExample;
        6       3     1     i   Ljava/lang/Integer;
       12       1     2 something   I

When you set a breakpoint on the commented line (line 31 in my source file), you're setting a breakpoint at bytecode index 10 (based on the LineNumberTable). The LocalVariableTable shows i only live from indices 6 through 9, hence why your debugger doesn't show it. Note that i's storage location, local variable slot 1, is not overwritten in the method; some debuggers will take advantage of this to show the value even if the variable is no longer live. (If you use a bytecode optimizer/obfuscator/packer/etc, it may alter the bytecode to reuse local variable slots to make the bytecode smaller, harder to debug, or more compressible. Of course it will probably remove the debug information entirely at the same time.)

Upvotes: 1

Related Questions