Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ending a Java thread in C (JNI)

Dear multithreading/Java/C/JNI gurus,

I have a slightly specific problem. I have a Java program that spawns threads. In the run() method, a call to C is made (via JNI), where at first, thread local variables are allocated in TLS, an then an event_loop is entered (so the default lifetime of the thread is determined by this loop).

My problem now is how to be able to shut down/kill the thread if something like SIGSEGV occurs. It would be important that the whole process and the other threads within it could continue. That's why we separated the threads by using TLS.

(I know, this is discouraged by some people and of course it is right to do defensive programming, trying to avoid such crashes in advance. This code is intended for a migration period only, since we are changing from C to Java. But this will take some time due to the small amount of resources we have.)

class MyThread extends Thread {
   run() {
      //wrapping the following with try-catch and throwing exception in signal 
      //handler on C side possible?
      callNativeCFunction(); //allocates TLS, enters event_loop()
   }
}

If I would use signal.h, would my signal handler be invoked in thread context? Would I have access to the TLS variables? Could I then somehow via the env-pointer to the JVM throw an exception to break out of the run()? Or I could invoke interrupt() onto the Java Thread, as e.g. mentioned in Bruce Eckel's book (see below).

Finally, one more question: SIGSEGV is Posix world, STATUS_ACCESS_VIOLATION is Windows world. When I tried the following in the C code in Windows:

 char *s = "hello world";
     *s = 'H';

I don't get SIGSEGV, (but STATUS_ACCESS_VIOLATION, I guess). Since I use signal.h, there is only a very limited set of signals available I can handle. Do you know how I could handle the above case, too?

Or would I be better off with pthreads on the C side and calling pthread_exit() in the signal handler (idea taken from first link below)?

That were my questions. I would be very thankful for any help. Many thanks in advance.

Helpful threads ;) I found:

  • Handling segfault signal SIGSEGV need to determine the cause of segfault using siginfo_t
  • how to debug SIGSEGV in jvm GCTaskThread
  • Bruce Eckel's Thinking in Java, 4th ed., p. 1194, “Checking for an interrupt”
like image 639
juniper Avatar asked May 22 '11 21:05

juniper


1 Answers

All the signal handler has to do is persuade the function (callNativeCFunction()) to return. If C has loops, have them check a module variable (signaled, shutdown, done, or similar).

If after the call to the function, the thread exits, it is all set. Otherwise maybe the function should return a status which indicates whether the thread should terminate or not.

like image 95
wallyk Avatar answered Sep 21 '22 14:09

wallyk