8

We have a Java server (Linux 64 bit) application that uses native code for its processing stuff. The native code also handles all multithreading issues and has been recently enhanced with fiber switching using boost::context.

The problem we're facing right now is that AttachCurrentThread fails for fiber-switched threads. After some long debugging and testing sessions we found the cause for this: the JVM seems to refuse threads with different stack pointers than given on its creation.

We verified this by simply attaching to the JVM from a pthread with modified (but valid) rsp which fails when rsp gets modified.

A possible fix would introduce some kind of event handling mechanism to decouple the callbacks from the fiber-switched threads, but I would really like to avoid that.

Does anybody know a workaround for this?

Is it possible to disable the stack checks (Oracle Java 1.7.0_40, 64 bit)?

Can we modify the native pthreads to point to the correct stack frames (I doubt we can)? (We can not set the stack frames in advance).

Neet
  • 3,937
  • 15
  • 18
  • 1
    I know it's not answering exactly your problem, but you could try to replace your boost::context fibers (implemented in C++) with some fibers implementation from within the Java world. They are often called coroutines in this context. Some existing implementations here: [Available Coroutine Libraries in Java](http://stackoverflow.com/questions/2846428/available-coroutine-libraries-in-java) – Martin Quinson Nov 01 '15 at 18:20
  • 1
    Did you ever find a solution to this? I'm attempting to utilize Boost.Coroutine and need to call back into Java space from JNI in such a routine which results in a lot of failures... – NuSkooler Jun 30 '16 at 16:54

1 Answers1

0

DISCLAIMER: This isn't really an answer, because I don't directly address the RSP-switch issue, but it was too long to put into a comment.

In my experience, you should attach the native thread exactly once, and detach exactly once before it exits. If you don't know if you've attached already, use this code:

jint rv = vm->GetEnv((void**)&env, JNI_VERSION_1_6);
if (rv == JNI_EDETACHED) {
    vm->AttachCurrentThread((void**)&env, 0);
}

I suggest first, making sure that you attach to the thread exactly once before any associated fibers are created, and detach exactly once from each native thread before it exits (or not at all, if the native threads do not terminate).

Wheezil
  • 3,157
  • 1
  • 23
  • 36