My device runs on Android 14. Trying to access the network within std::thread
results in an app crash.
Native code:
extern "C" JNIEXPORT jstring JNICALL
Java_com_example_myapplication_MainActivity_stringFromJNI(
JNIEnv* env,
jobject /* this */) {
std::string hello = "Hello from C++";
std::thread t{[&]{
gethostbyname("www.google"); // app crash
}};
return env->NewStringUTF(hello.c_str());
}
Java code:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
binding = ActivityMainBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot());
// Example of a call to a native method
TextView tv = binding.sampleText;
new Thread(this::stringFromJNI).start();
}
Logcat message:
Fatal signal 6 (SIGABRT), code -1 (SI_QUEUE) in tid 15894 (e.myapplication), pid 15894 (e.myapplication)
P.S. android.permission.INTERNET
is already declared in the manifest. Accessing the network in Java has no problem.
Does anyone know what's going on here?
I tried the follow code, and it works fine:
extern "C" JNIEXPORT jstring JNICALL
Java_com_example_myapplication_MainActivity_stringFromJNI(
JNIEnv* env,
jobject /* this */) {
std::string hello = "Hello from C++";
gethostbyname("www.google"); // works fine
return env->NewStringUTF(hello.c_str());
}
My device runs on Android 14. Trying to access the network within std::thread
results in an app crash.
Native code:
extern "C" JNIEXPORT jstring JNICALL
Java_com_example_myapplication_MainActivity_stringFromJNI(
JNIEnv* env,
jobject /* this */) {
std::string hello = "Hello from C++";
std::thread t{[&]{
gethostbyname("www.google"); // app crash
}};
return env->NewStringUTF(hello.c_str());
}
Java code:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
binding = ActivityMainBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot());
// Example of a call to a native method
TextView tv = binding.sampleText;
new Thread(this::stringFromJNI).start();
}
Logcat message:
Fatal signal 6 (SIGABRT), code -1 (SI_QUEUE) in tid 15894 (e.myapplication), pid 15894 (e.myapplication)
P.S. android.permission.INTERNET
is already declared in the manifest. Accessing the network in Java has no problem.
Does anyone know what's going on here?
I tried the follow code, and it works fine:
extern "C" JNIEXPORT jstring JNICALL
Java_com_example_myapplication_MainActivity_stringFromJNI(
JNIEnv* env,
jobject /* this */) {
std::string hello = "Hello from C++";
gethostbyname("www.google"); // works fine
return env->NewStringUTF(hello.c_str());
}
Share
Improve this question
edited Mar 14 at 17:59
Remy Lebeau
601k36 gold badges507 silver badges851 bronze badges
asked Mar 14 at 17:55
larrylarry
131 silver badge4 bronze badges
1
|
1 Answer
Reset to default 1You are not calling join()
or detach()
on the std::thread
object before it is destroyed when your stringFromJNI
function exits. So, the std::thread
destructor will call std::terminate()
to kill the process.
https://en.cppreference/w/cpp/thread/thread/%7Ethread
If
*this
has an associated thread (joinable() == true
),std::terminate()
is called.Notes
A thread object does not have an associated thread (and is safe to destroy) after
- it was default-constructed.
- it was moved from.
join()
has been called.detach()
has been called.
C++20 adds std::jthread
, which does not have this behavior. Its destructor will join()
the thread for you:
https://en.cppreference/w/cpp/thread/jthread/%7Ejthread
If
*this
has an associated thread (joinable() == true
), callsrequest_stop()
and thenjoin()
.
That being said, since your Java code is already calling stringFromJNI
in a thread, there is no need for stringFromJNI
to create its own thread.
std::jthread
instead ofstd::thread
, as the former will not callstd::terminate()
it is destroyed, unjoined. – Drew Dormann Commented Mar 14 at 18:02