最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

c++ - Accessing network within std::thread results in app crash on Android - Stack Overflow

programmeradmin2浏览0评论

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
  • You might consider using std::jthread instead of std::thread, as the former will not call std::terminate() it is destroyed, unjoined. – Drew Dormann Commented Mar 14 at 18:02
Add a comment  | 

1 Answer 1

Reset to default 1

You 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), calls request_stop() and then join().

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.

发布评论

评论列表(0)

  1. 暂无评论