unexpected exception when using JNI

J

James Ly

Hi,

I am having a very intermittent problem with JNI (tried with Java
versions 1.3.1_09/1.4.1_02/1.4.2_02) on Linux 8.0 (kernel 2.4.18).

From a C program, I am first starting up a JVM. Here is the relevant
C-code for this:
vm_args.version = JNI_VERSION_1_2;
vm_args.options = options;
vm_args.nOptions = 2;
vm_args.ignoreUnrecognized = JNI_TRUE;

/* Create the Java VM */
res = JNI_CreateJavaVM(&jvm,(void **) &env,&vm_args);
if (res < 0) {
fprintf(stderr, "Can't create Java VM\n");
//exit(1);
}

Once the JVM is created, I load one of the Java class (Test). Here is
the C-code for that:
char *className = "Test";
// Find the Test class
testClass = (*env)->FindClass (env, className);
// If not found, return error.
if (testClass == 0) {
exp = (*env)->ExceptionOccurred (env);
if (exp) {
(*env)->ExceptionDescribe (env);
}
fprintf (stderr, "Can't find the %s class\n", className);
}

In the Java world, there are 2 relevant classes for the problem:

* PeggingThread: PeggingThread class sends a peg of user info to track
usage. It listens for requests coming into it and then opens a socket
and sends a message over that socket for each of the requests. The
reason for doing this as a thread is that I don't want to block the
application while opening/sending msg to the socket.

* Test: The Test class has a static variable for the PeggingThread,
and has a static block which sends a request to the PeggingThread.

private static final PeggingThread peggingThread = new
PeggingThread();
static {
if (Test.sentRunningInfo == false) {
Test.peggingThread.receiveRequest("");
Test.sentRunningInfo = true;
}
}

The interminttent problem that I am seeing is that when running the
above code, I get the following error and the application quits almost
half the time:

An unexpected exception has been detected in native code outside the
VM.
Unexpected Signal : 11 occurred at PC=0x40628ff0
Function name=(N/A)
Library=/lib/i686/libpthread.so.0

NOTE: We are unable to locate the function name symbol for the error
just occurred. Please refer to release documentation for
possible
reason and solutions.

and then a list of all the shared libraries that were loaded.

Going through the core file that gets generated using gdb, backtrace
indicates different places where the crash heppened. So, it doesn't
help much. If I remove the static block from the Test class, ie. no
sending of the peg for user info, I don't see any crashes and the
application runs fine.

Would anyone out there know why I am seeing such an issue. To me it
looks like there is some race condition, but this never happens when I
run in a pure Java environment (Java code not using JNI). Any info
would help. I have been struggling with this for about 2 weeks now.

Thanks.

James Ly
 
G

Gordon Beaton

I am having a very intermittent problem with JNI (tried with Java
versions 1.3.1_09/1.4.1_02/1.4.2_02) on Linux 8.0 (kernel 2.4.18).

There is no "Linux 8.0". Your linux version is 2.4.18.
The interminttent problem that I am seeing is that when running the
above code, I get the following error and the application quits
almost half the time:

An unexpected exception has been detected in native code outside the
VM.
Unexpected Signal : 11 occurred at PC=0x40628ff0
Function name=(N/A)
Library=/lib/i686/libpthread.so.0

At the risk of stating the obvious, you probably have an error in your
code. Whether it's a race condition or something else is impossible to
say from here. Are you updating some common data structures from
several threads?

Here are a few other possibilities (this is not an exhaustive list):

- you are using the value of variable that hasn't been assigned any
value yet
- you have written past the bounds of an array or struct
- you have freed a block of memopry more than once
- you are using a pointer to an object that has gone out of scope
- you have passed a pointer of some type to a function expecting a
pointer of some other type.

All of the above can cause erratic behaviour, with the program failing
at some place unrelated to the actual error (or not at all).

Do you have all warnings turned on when you compile (gcc -Wall)? Also
try testing your native code outside of Java, using a tool like
purify, mpatrol, valgrind, electric fence or similar. Try to remove
parts of the code (whole functions) and see if the problem persists.

/gordon
 
G

gailw

Two possibilities.

1. I see the exception is in thread library. If you're threading in C/C++,
you also have to do the jni operation "AttachCurrentThread()" for each
thread after the main thread - each thread gets it's own jvm environment.

2. You set vm_args->nOptions = 2, and vm_args->options = options.
But where do you initialize options[0] and options[1]?

Jim W.
 
J

James

gailw said:
Two possibilities.

1. I see the exception is in thread library. If you're threading in C/C++,
you also have to do the jni operation "AttachCurrentThread()" for each
thread after the main thread - each thread gets it's own jvm environment.

2. You set vm_args->nOptions = 2, and vm_args->options = options.
But where do you initialize options[0] and options[1]?

Jim W.


--


James Ly said:
Hi,

I am having a very intermittent problem with JNI (tried with Java
versions 1.3.1_09/1.4.1_02/1.4.2_02) on Linux 8.0 (kernel 2.4.18).

From a C program, I am first starting up a JVM. Here is the relevant
C-code for this:
vm_args.version = JNI_VERSION_1_2;
vm_args.options = options;
vm_args.nOptions = 2;
vm_args.ignoreUnrecognized = JNI_TRUE;

/* Create the Java VM */
res = JNI_CreateJavaVM(&jvm,(void **) &env,&vm_args);
if (res < 0) {
fprintf(stderr, "Can't create Java VM\n");
//exit(1);
}

Once the JVM is created, I load one of the Java class (Test). Here is
the C-code for that:
char *className = "Test";
// Find the Test class
testClass = (*env)->FindClass (env, className);
// If not found, return error.
if (testClass == 0) {
exp = (*env)->ExceptionOccurred (env);
if (exp) {
(*env)->ExceptionDescribe (env);
}
fprintf (stderr, "Can't find the %s class\n", className);
}

In the Java world, there are 2 relevant classes for the problem:

* PeggingThread: PeggingThread class sends a peg of user info to track
usage. It listens for requests coming into it and then opens a socket
and sends a message over that socket for each of the requests. The
reason for doing this as a thread is that I don't want to block the
application while opening/sending msg to the socket.

* Test: The Test class has a static variable for the PeggingThread,
and has a static block which sends a request to the PeggingThread.

private static final PeggingThread peggingThread = new
PeggingThread();
static {
if (Test.sentRunningInfo == false) {
Test.peggingThread.receiveRequest("");
Test.sentRunningInfo = true;
}
}

The interminttent problem that I am seeing is that when running the
above code, I get the following error and the application quits almost
half the time:

An unexpected exception has been detected in native code outside the
VM.
Unexpected Signal : 11 occurred at PC=0x40628ff0
Function name=(N/A)
Library=/lib/i686/libpthread.so.0

NOTE: We are unable to locate the function name symbol for the error
just occurred. Please refer to release documentation for
possible
reason and solutions.

and then a list of all the shared libraries that were loaded.

Going through the core file that gets generated using gdb, backtrace
indicates different places where the crash heppened. So, it doesn't
help much. If I remove the static block from the Test class, ie. no
sending of the peg for user info, I don't see any crashes and the
application runs fine.

Would anyone out there know why I am seeing such an issue. To me it
looks like there is some race condition, but this never happens when I
run in a pure Java environment (Java code not using JNI). Any info
would help. I have been struggling with this for about 2 weeks now.

Thanks.

James Ly


Hi Jim,

The options are initialized as:
JavaVMOption options[2];
char classpathStr [1024];
char *userClasspath;
userClasspath = getenv ("USER_CLASSPATH");
sprintf (classpathStr, "-Djava.class.path=%s", userClasspath);

options[0].optionString = classpathStr;
options[1].optionString = "-Djava.compiler=NONE";

James
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,015
Latest member
AmbrosePal

Latest Threads

Top