9

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:

Community
  • 1
  • 1
juniper
  • 311
  • 5
  • 13

1 Answers1

2

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.

wallyk
  • 56,922
  • 16
  • 83
  • 148
  • Yes, that is one of the ways Bruce Eckel mentions in his book. But since it is dangerous to let the thread run after it caused something like SIGSEGV (I got an EXCEPTION_CONTINUE_EXECUTION), I searched for a way to immediately shut it down out of the signal handler (maybe invoking the interrupt() method on the Java object; which, of course may also be dangerous in the signal handler; but I already successfully invoked a self written getThreadId() method on my thread objects right from the signal handler). – juniper May 24 '11 at 12:57
  • Furthermore, there is still the open point how to catch the STATUS_ACCESS_VIOLATION in Windows. Do you know a way, e.g. via a third library? I found GNU libsigsegv ( http://libsigsegv.sourceforge.net/), but was not sure, whether it is the right one for my problem. – juniper May 24 '11 at 12:58
  • We currently solved this for the Windows side using structured exception handling (SEH), as mentioned here: http://www.oracle.com/technetwork/java/javase/signals-139944.html#gbzdn So, the function callNativeCFunction() on the C side starts with __try and ends with __except, so our event loop is wrapped by these two macros. If an exception occurs, program flow jumps to the __except clause (i.e. jumping out of our event loop) and the thread is effectively ended because callNativeCFunction() ends, returns to the Java side, where the run() method (and thus the whole thread) ends. – juniper Jul 24 '11 at 17:07
  • What now remains is finding a solution for the Linux case, which will be based on signal.h, I think. I will let you know if I know more. – juniper Jul 24 '11 at 17:07