SIGSEV when calling JAVA callback method from native code after multiple calls - java

I am using JNA to pass a callback function from Java to native code. I am able to call the java inteface method ok, the problem is after about 40 calls of the function i get a SIGSEV and the program terminates.
The SIGSEV occurs at the line when the native code calls the method.
Is this related so some garbage collection on the Java function handle? Is there a way to prevent this?
Note: The closest thread on the sight was "SIGSEV when calling Java method from native pthread". He seemed solve his problem on the native side though by making things global.
I have tried making the java method synchronous but this has not helped. I also modified the native call to launch a pthread and then call the java method. When doing this, the method can be called maybe 1000 times then i get the SIGSEV
on the java side I have
public interface handler extends Callback {
void invoke();
}
static class test_start implements handler {
public synchronized void invoke() {
System.out.println("Hello");
}
}

You are right, that you suspect GC to be your problem, which is also documented in JNA.
Summary: You'll need to keep a strong reference to your Callback Handler on the java side to prevent garbage collection.
The implementation is highly dependent on your architecture. If your handler is global, you can save it in a static field (GC will normally collect static field data only when class is unloaded). If your handler is tied to a concrete java class, you could use a static WeakHashMap to keep the reference until the java object is collected (assuming this also indicates, that the native side will not call the handler anymore). If the handler is tied to a fixed lifecycle, I would implement an AutoCloseable helper object, that unregisters your handler on close.
It should be noted, that in all implementations, you must make sure that your handler is kept referenced. For the AutoClosable implementation running Reference#reachabilityFence​ from the close method after the handler is unregister would be a sane decision.

Related

What does an "asynchronous method" mean in Java?

I am in the process of working through the android billing example for an app. The sample app refers to an asynchronous method. I have had a look on the web and I cant seem to find a good definition, please can someone help with an example.
Sample as follows:
// Start setup. This is asynchronous and the specified listener
// will be called once setup completes.
mHelper.startSetup(new IabHelper.OnIabSetupFinishedListener() {
public void onIabSetupFinished(IabResult result) {
Is it a method that does not immediately return a result?
If I am not mistaken, you are referring to this method startSetup that accepts a final OnIabSetupFinishedListener and supposedly sets up the billing.
What you seem to be confused about, is this rather syntactically obscure feature of Java called the anonymous inner class.
Let me attempt to answer your question to make it easier:
Is it a method that does not immediately return a result?
Yes, sort of (it of course does not return anything for it is a void method). It, simply speaking, is a method that accepts an instance of the interface OnIabSetupFinishedListener and does some of its job asynchronously as stated in the Javadoc and returns nothing:
This will start up the setup process asynchronously.
Thus, this method is similar to what any other void Java method looks like. The only additional implementation information is that some kind of communication is set up between the listener you pass to this method and some other objects.
But that communication is going to happen at a later point in time, not at the time you call this method, startSetup. Thus, what is important is the call site, i.e. how you are going to call this method in your own app. This, hopefully, happens at the time of setting up your app and you need to get it quickly running and hence this method provides a callback mechanism and returns as soon as possible in a synchronous manner without unnecessary delay. This means your calling thread can make progress and the listener you passed to this method can be utilized later in some other thread when an appropriate event occurs.
The confusion also comes in part because of the way anonymous inner classes are typically coded. Thus, your call site may look like the following:
mHelper.startSetup(new IabHelper.OnIabSetupFinishedListener() {
public void onIabSetupFinished(IabResult result) {
if (!result.isSuccess()) {
// Oh noes, there was a problem.
Log.d(TAG, "Problem setting up In-app Billing: " + result);
}
// Hooray, IAB is fully set up!
}
});
Here, you are providing an anonymous implementation of the interface OnIabSetupFinishedListener directly at the call site (without actually creating a separate class implementing that interface, using the construct like class MyListener implements OnIabSetupFinishedListener).
Yes. In this context, "asynchronous" means that the method will return immediately and execution will continue with the statement following the method call. Sometime later, the onIabSetupFinished(...) method will be called on the listener. This is called a callback. An important consideration with asynchronous callbacks is what thread they are called in. You'll need to refer to the documentation for this API to find that out.
An asynchronous method is not a typically request/response
You can think of this like a promise or something that will reply without pooling.
In your case you are creating an anonymous listener that will resolve the promise here
public void onIabSetupFinished(IabResult result){
//you will eventually get the response here
}

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.

Attaching third party thread to vm when using jni

I'm writing a Java program that uses a hardware driver written in c. This hardware driver starts a callback thread, and you can register callback functions to be called when stuff happens. How can I attach this thread to the jvm so that it can call the Java methods for these callbacks? I only have the thread id returned from the start_callbacks() function, returned as an int, but it is the pthread_t used in the call to pthread_create().
One way I found is to use pthread_once on the start of every callback function and attach the thread there. But then there is no way to detach it. I tried to use pthread_cleanup_push/pop, but they need to be called as a pair so that didn't work.
It seems to me that my only option to do this right is to attach and detach the thread at every callback call. Or rewrite the driver somewhat, which I really don't want to do.
Is there something I missed?
That's exactly what the JNI calls AttachCurrentThread() and DetachCurrentThread() are for.
The solution to you problem can be resolved with thread_local storage (C++ 11 and higher). This allows you to attach to an arbitrary thread, and then it will automatically detach when the thread exist (even when you didn't create the thread and have no control over it's life cycle).
A sample example of how to implement that in C++ can be found in my answer here:
https://stackoverflow.com/a/59934966/8367574

Detecting thread interruption with JNA native wait call (Windows)

I'm trying to write some code that performs a wait via JNA (e.g. by calling the Kernel32 function WaitForSingleObject), but I'd also like the wait to finish if Thread.interrupt() is called; I assume Java uses something like an Event object to implement interruption; is there any way of getting the Event from Java in order to use it in a call to WaitForMultipleObjects? Or is there any other way I could arrange for my wait to finish if the thread is interrupted?
Java supports it via NIO and very few people are aware of, the class in question is abstract but that's no issue:
java.nio.channels.spi.AbstractInterruptibleChannel. It has 3 methods of interest: begin() and end(), those are final, plus that one you have to implement: "protected abstract void implCloseChannel() throws IOException"
The method is going to be called from the thread invoking interrupt(), so be careful.
The use is very simple: call begin before entering the native code and end() upon return. Handling the interruption in implCloseChannel.
Happy coding!
Having found a bit of time to do some more research, I went for a digging expedition in the OpenJDK source code this morning. It turns out that starting with the native implementation was wrong; there's a pure-Java mechanism for doing this.
The class sun.misc.SharedSecrets has a static method getJavaLangAccess(), which returns an object with a method blockedOn(Thread, sun.nio.ch.Interruptible). This can be used to arrange for Thread.interrupt() to call a method supplied by one of my own objects, at which point I can create my own interruption Event object with which I can ensure waits are terminated as required.
Doing this introduces dependencies on sun's implementation of the Java class library, but probably less so than digging through the JVM's native state to try to extract an event handle that it uses internally.

Does oneway declaration in Android .aidl guarantee that method will be called in a separate thread?

I am designing a framework for a client/server application for Android phones. I am fairly new to both Java and Android (but not new to programming in general, or threaded programming in particular).
Sometimes my server and client will be in the same process, and sometimes they will be in different processes, depending on the exact use case. The client and server interfaces look something like the following:
IServer.aidl:
package com.my.application;
interface IServer {
/**
* Register client callback object
*/
void registerCallback( in IClient callbackObject );
/**
* Do something and report back
*/
void doSomething( in String what );
.
.
.
}
IClient.aidl:
package com.my.application;
oneway interface IClient {
/**
* Receive an answer
*/
void reportBack( in String answer );
.
.
.
}
Now here is where it gets interesting. I can foresee use cases where the client calls IServer.doSomething(), which in turn calls IClient.reportBack(), and on the basis of what is reported back, IClient.reportBack() needs to issue another call to IClient.doSomething().
The issue here is that IServer.doSomething() will not, in general, be reentrant. That's OK, as long as IClient.reportBack() is always invoked in a new thread. In that case, I can make sure that the implementation of IServer.doSomething() is always synchronized appropriately so that the call from the new thread blocks until the first call returns.
If everything works the way I think it does, then by declaring the IClient interface as oneway, I guarantee this to be the case. At least, I can't think of any way that the call from IServer.doSomething() to IClient.reportBack() can return immediately (what oneway is supposed to ensure), yet IClient.reportBack still be able to reinvoke IServer.doSomething recursively in the same thread. Either a new thread in IServer must be started, or else the old IServer thread can be re-used for the inner call to IServer.doSomething(), but only after the outer call to IServer.doSomething() has returned.
So my question is, does everything work the way I think it does? The Android documentation hardly mentions oneway interfaces.
The oneway keyword means that if that call results in an IPC (i.e. the caller and callee are in different processes) then the calling process will not wait for the called process to handle the IPC. If it does not result in an IPC (i.e. they're both in the same process), the call will be synchronous. It's an unfortunate detail that simplifies the implementation of binder IPC a lot. If they're in the same process, the call is just a regular java method call.
From Android document
The oneway keyword modifies the behavior of remote calls. When used, a remote call does not block; it simply sends the transaction data and immediately returns. The implementation of the interface eventually receives this as a regular call from the Binder thread pool as a normal remote call. If oneway is used with a local call, there is no impact and the call is still synchronous
For example, we have a Client app and a Server app, and an AIDL interface like
interface IRemoteService {
oneway void onewayFunctionCall(int value); // function take 1 seconds to complete
void noneOneWayFunctionCall(int value); // function take 1 seconds to complete
}
oneway will affect the method in the Client app (remote call).
For example, we call server service from Client app like
for (i in 0..5) {
Log.i("TAG", "call $i") // fired each 1 second
iRemoteService?.noneOneWayFunctionCall(i)
}
// run synchronous
for(i in 0..5) {
serverService.onewayFunctionCall(i); // fired right after previous function call
}
// run asynchronous
Because oneway method call and don't wait for the result so it must be void function.
In the above case, we call server service from a single thread (main thread) so the function can block. So I think oneway only useful in a single thread.
If we call from a single thread in the client app, the method in the server (oneway / none oneway) still executes synchronously.
If we use multiple threads in the client app to call server service, the method in the server will execute asynchronously

Categories

Resources