JNI Global Static Variables in C++ Code - java

I have a JNI C++ code being called from a multi-threaded java application
This C++ code has 2 global static variables a boolean and a string.
For some reason i keep getting segmentation fault from this code . Any idea what could lead to this ? I know this is not thread safe, but i am treating the variables as read only from the java application and only the C++ code is able to modify the values of these variables
Help much appreciated
EDIT : This code runs on a Linux machine . And runs for months at a time without any issues, then it issues a signal 11 segmentation fault and the JVM crashes.

If you're calling the C++ code from multiple threads, and the C++ code has global static variables, then it would be amazing if it worked. The simplest thing to try is to put a lock around the call, i.e. in the Java side change
native int callToCppFunction(int parameter);
to
synchronized native int callToCppFunction(int parameter);
to ensure that only one thread can be in the C++ code at a time.
Then there's another possible issue, which I bumped on about a year ago: apparently in Windows dlls it may not be enough to serialize calls to it (i.e. use synchronized). They may also require to be called from the same thread each time. This answer offers an explanation to how that can be. The solution is to make a single threaded executor to the Java side, and route all calls to the native code through it.

Related

Java What Happens When a Thread is Started Until It Starts Running

What is the sequence of events that occur between calling Thread.start and Thread.run being called? I ask because mostly out of curiosity, and because I can't seem to trace the native calls to find their implementation, but also to answer some questions I had about what I can expect after starting a Thread.
This question gives a good high level answer, but I'm looking for a more in-depth answer + links to source code is possible.
I'm not sure how every native method of a Java Thread is hooked up, but Java Threads use pthreads in the native layer. https://en.wikipedia.org/wiki/POSIX_Threads
The Thread#start method in Java creates (and starts) a VMThread, which is backed by a pthread. The VMThread is backed by JNI and most of its calls wind up at vm/Thread.c (e.g. https://android.googlesource.com/platform/dalvik/+/eclair-release/vm/Thread.c).
E.g. the VMThread#create calls JNI method Dalvik_java_lang_VMThread_create and that calls the dvmCreateInterpThread function in vm/Thread.c
I hope this is a good start for you to start Googling around what exactly happens between Thread creation and its start.
Streets of Boston pointed me in the right direction, where I found https://android.googlesource.com/platform/art/+/marshmallow-release/runtime/ . I will update this answer as soon as I get a chance to read through the code and grok it.

How are the static variables in C++ code managed with JNI?

My question is, Assume I have a c++ class with singleton and through JNI methods I call this singleton, does each time I call from java to c++ the singleton variable changed because its static, or it remains the same ? and does each time I call from java to c++ it run the method on new thread or no?
Example Code:
in Java:
class NativeLib
{
public native void updateFrame();
}
in C/C++ :
JNIEXPORT void JNICALL Java_com_Company_NativeLib_NativeLib_updateFrame()
{
sceneManager::getInstance()->updateFrame();
}
Does sceneManager::getInstance() at each call return new instance or the latest created instance since its a static variable.
my main problem in android my app crash without showing any kind of logCat information why it crashed.
but if I comment the sceneManager::getInstance()->updateFrame(); , it never crash so what I think is when ever Java make a call to C++ it is in a new thread which mean static variables does not
Think of the VM as a library of C/C++ code that your application has called into. Sometimes it calls back into your code.
Singletons will not be recreated -- it's just a method call. The Dalvik VM threads are just pthreads, and whichever thread executes the native call from Java-language code will be the thread that executes your C++ code.
Your best bet is to attach a native debugger. FWIW, one way to crash with nothing in logcat is to have native recursion that overflows the stack. Another way is to change the signal handlers for SIGSEGV / SIGBUS and friends.

Notifying java object from C/C++ code?

I am wondering is it possible to notify( notify() ) a java object with native code?
For example let's say we have a thread in java which is waiting for a signal as below.
void _do_something() throws Exception{
synchronized(__lock_){
__lock_.wait();
}
}
Then is it possible to notify the __lock_ object from a native code?!
Should I pass the __lock_ object to the c code? so how and how C code call the notify() method.
Any help is appreciated.
Thanks in advance.
This is very doable from native code. You need to use JNI though...
Then is it possible to notify the _lock object from a native code?!
Sure, as long as your native code has a handle to the _lock object, all you have to do is to synchronize and call notify on it (like you would call any other java object from native code).
Should I pass the _lock object to the c code?
Yes. Both because you need it when you call the CallVoidMethod() JNI function to call notify() but also because you need to enter/exit Monitor of that object (the JNI equivalent way of saying "synchronized(_lock)"
so how and how C code call the notify() method
First you need to understand the basics of mapping your native code to something you can call from java. Then you need to understand how to call back into java from that native code and when you understand that, it is all a matter of learning how to use MonitorEnter, CallVoidMethod and MonitorExit.
Unfortunately, JNI sometimes seems to be designed to keep people away. When you're new at it, it is kind of hard to do proper debugging. I would recommend to start small to get a grip of it and wait with the real stuff until you understand the basics.
My best advice with JNI is to stick to the rules (at least in the beginning), check exceptions after every call (and dump them to stderr or something when you get them) and run your java with -Xcheck:jni.
There are plenty of tutorials around, I found this one in the top10-list when I googled, it seems ok.
Good luck!

Context switched native thread can't attach to JVM

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).
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).

Signals in Java

I was use C++ signals
sigaction
struct sigaction sigact;
and set all attributes to use signals
now I want to use it in Java what's the equivalent in java
to the include "signal.h"
I have two threads:
one run from the beginning of the program
and the other run at the signal Alarm
I was implement the functionality in C++ using Signals as shown and now I want to implement it using java
Edited to put my Goal:
actually my Goal to run the second Thread When the signal arrives from the first thread
Thus sounds like a typical "XY-Problem".
In plain Java you have no access to OS-signal. They are platform specific and Java strifes to be platform agnostic. Also: calling Java from a signal handler with JNI might be "fun" (as explained in Dwarf Fortress).
So you have to go back to the drawing board and think about what is the problem you want to solve and stop thinking about how to solve it with signals.
That said: if you insist on signals and are not afraid to use internal stuff which might change on a whim: Take a look at sun.misc.Signal.
EDIT Now the question made it clear, that the signalling takes place within one JVM. For this signals are definitely the wrong thing in Java.
So the simplest solution is to create and start the second thread directly from within the first thread. No signalling required.
The next best solution is to code a "rendezvous point" using Object.wait() in the second thread (using any object instance but the Thread itself) and Object.notify() or notifyAll() from the first thread. Searching for these terms in a Java tutorial will bring up enough examples.

Categories

Resources