Monday, February 10, 2014

Java launcher debug

If you ever want to set your development environment so that java utilities should print some debug information you can use _JAVA_LAUNCHER_DEBUG. Note that this environment variable’s value is not relevant, as long as its set to something. So, if you want to disable debugging you have to unset it. Following is an example with javac and java

Compile a java program

Note the details below starting from the launcher state variables (e.g. full java version), arguments to java, the config values read from jvm.cfg, path of libjvm.so, and JavaJVM arguments. These are very handy when debugging a build.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
$ (export _JAVA_LAUNCHER_DEBUG=1 \
&& javac TowerOfHanoi.java \
&& unset _JAVA_LAUNCHER_DEBUG)
----_JAVA_LAUNCHER_DEBUG----
Launcher state:
        debug:on
        javargs:on
        program name:java
        launcher name:java
        javaw:off
        fullversion:1.7.0_45-b18
        dotversion:1.7
        ergo_policy:NEVER_ACT_AS_A_SERVER_CLASS_MACHINE
Command line args:
argv[0] = javac
argv[1] = TowerOfHanoi.java
JRE path is /usr/java/jdk1.7.0_45/jre
jvm.cfg[0] = ->-server<-
jvm.cfg[1] = ->-client<-
jvm.cfg[2] = ->-hotspot<-
jvm.cfg[3] = ->-classic<-
jvm.cfg[4] = ->-native<-
jvm.cfg[5] = ->-green<-
1 micro seconds to parse jvm.cfg
Default VM: server
Does `/usr/java/jdk1.7.0_45/jre/lib/amd64/server/libjvm.so' exist ... yes.
mustsetenv: FALSE
JVM path is /usr/java/jdk1.7.0_45/jre/lib/amd64/server/libjvm.so
1 micro seconds to LoadJavaVM
JavaVM args:
    version 0x00010002, ignoreUnrecognized is JNI_FALSE, nOptions is 7
    option[ 0] = '-Dsun.java.launcher.diag=true'
    option[ 1] = '-Dapplication.home=/usr/java/jdk1.7.0_45'
    option[ 2] = '-Djava.class.path=/usr/java/jdk1.7.0_45/lib/tools.jar:/usr/java/jdk1.7.0_45/classes'
    option[ 3] = '-Xms8m'
    option[ 4] = '-Dsun.java.command=com.sun.tools.javac.Main TowerOfHanoi.java'
    option[ 5] = '-Dsun.java.launcher=SUN_STANDARD'
    option[ 6] = '-Dsun.java.launcher.pid=18510'
1 micro seconds to InitializeJVM
Main class is 'com.sun.tools.javac.Main'
App's argc is 1
    argv[ 0] = 'TowerOfHanoi.java'
1 micro seconds to load main class
----_JAVA_LAUNCHER_DEBUG----

Run the java program

Similary, we can see all the above when invoking a java program.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
$ (export _JAVA_LAUNCHER_DEBUG=1 \
&& java TowerOfHanoi \
&& unset _JAVA_LAUNCHER_DEBUG)
----_JAVA_LAUNCHER_DEBUG----
Launcher state:
        debug:on
        javargs:off
        program name:java
        launcher name:java
        javaw:off
        fullversion:1.7.0_45-b18
        dotversion:1.7
        ergo_policy:DEFAULT_ERGONOMICS_POLICY
Command line args:
argv[0] = java
argv[1] = TowerOfHanoi
JRE path is /usr/java/jdk1.7.0_45/jre
jvm.cfg[0] = ->-server<-
jvm.cfg[1] = ->-client<-
jvm.cfg[2] = ->-hotspot<-
jvm.cfg[3] = ->-classic<-
jvm.cfg[4] = ->-native<-
jvm.cfg[5] = ->-green<-
1 micro seconds to parse jvm.cfg
Default VM: server
Does `/usr/java/jdk1.7.0_45/jre/lib/amd64/server/libjvm.so' exist ... yes.
mustsetenv: FALSE
JVM path is /usr/java/jdk1.7.0_45/jre/lib/amd64/server/libjvm.so
1 micro seconds to LoadJavaVM
JavaVM args:
    version 0x00010002, ignoreUnrecognized is JNI_FALSE, nOptions is 5
    option[ 0] = '-Dsun.java.launcher.diag=true'
    option[ 1] = '-Djava.class.path=.'
    option[ 2] = '-Dsun.java.command=TowerOfHanoi'
    option[ 3] = '-Dsun.java.launcher=SUN_STANDARD'
    option[ 4] = '-Dsun.java.launcher.pid=18692'
1 micro seconds to InitializeJVM
Main class is 'TowerOfHanoi'
App's argc is 0
1 micro seconds to load main class
----_JAVA_LAUNCHER_DEBUG----
##  Move disk 1 from A to B
##  Move disk 2 from A to C
##  Move disk 1 from B to C
##  Move disk 3 from A to B
##  Move disk 1 from C to A
##  Move disk 2 from C to B
##  Move disk 1 from A to B
##  Move disk 4 from A to C
##  Move disk 1 from B to C
##  Move disk 2 from B to A
##  Move disk 1 from C to A
##  Move disk 3 from B to C
##  Move disk 1 from A to B
##  Move disk 2 from A to C
##  Move disk 1 from B to C

Java program used above

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class TowerOfHanoi {
    public int move(int n, char from, char mid, char to) {
        if (n < 1) {
            return 0;
        }
 
        move(n-1, from, to, mid);
        System.out.println("##  Move disk " + n + " from " + from + " to " + to);
        move(n-1, mid, from, to);
 
        return 0;
    }
 
    public static void main(String argv[]) {
        TowerOfHanoi toh = new TowerOfHanoi();
        toh.move(4, 'A', 'B', 'C');
    }
};