If you happen to try to debug any Java JNI programs using gdb on GNU/Linux you will soon come across error messages.
For example :
$ gdb --args java MyJavaProgramUsingJNI
The reason for this is that the java program mucks around with LD_LIBRARY_PATH and that prevents gdb from running correctly.
To overcome this, you have to run your Java program and place a pause in the Java code, such as reading a key, and then in another shell, run gdb to attach to the running Java process.
You can then set your breakpoint on your JNI code and debug it.
Here is an example :
Compile your Java program:
Generate the JNI header file:
Create and compile your C code library:
Run it:
Run Java program in shell A and attach debugger in session B:
Attach debugger:
For example :
$ gdb --args java MyJavaProgramUsingJNI
cannot find user-level thread for LWP nnn: generic error
warning: Cannot initialize thread debugging library: versions of libpthread and libthread_db do not match
The reason for this is that the java program mucks around with LD_LIBRARY_PATH and that prevents gdb from running correctly.
To overcome this, you have to run your Java program and place a pause in the Java code, such as reading a key, and then in another shell, run gdb to attach to the running Java process.
You can then set your breakpoint on your JNI code and debug it.
Here is an example :
Compile your Java program:
$ javac JNITest.java
Generate the JNI header file:
$ javah -jni JNITest.java
Create and compile your C code library:
$ cat jnilib.c #include "JNITest.h" JNIEXPORT jint JNICALL Java_JNITest_addValues( JNIEnv *env, jobject jobj, jint a, jint b ) { int res = a + b; return res; } $ gcc -o libjnilib.so -shared -I /opt/jdk1.5.0_16/include -I /opt/jdk1.5.0_16/include/linux jnilib.c
Run it:
$ java JNITest Result = 75
Run Java program in shell A and attach debugger in session B:
A$ java JNITestFind running Java process ...
B$ ps -ef ... user 17809 16492 7 21:28 pts/1 00:00:00 java JNITest user 17821 14042 4 21:28 pts/2 00:00:00 bash user 17845 17821 0 21:28 pts/2 00:00:00 ps -ef
Attach debugger:
B$ gdb -p 17809 ... (gdb) break Java_JNITest_addValues Breakpoint 1 at 0x8ca02402: file jnilib.c, line 5. (gdb) cont Continuing. [Switching to Thread 0xb7e866b0 (LWP 17809)] Breakpoint 1, Java_JNITest_addValues (env=0x84258b8, jobj=0xbfd2e6d8, a=25, b=50) at jnilib.c:5 5 int res = a + b; (gdb) (gdb) print a $1 = 25 (gdb) print b $2 = 50 (gdb) cont Continuing.
JNI now deprecated?
JNI vs JNA: Which is best for your project?