[FIXED] Add item to ArrayList in C++ native crash the android app on Click Listener

Issue

I have following method in C++ native JNI :

extern "C" JNIEXPORT jintArray JNICALL
Java_com_haha_datastructuresample_MainActivity_arrayListFromJNI(
        JNIEnv *env,
        jobject) {

    //---------------------ArrayList-----------------
    auto *list = new ArrayList<int>();

    list->size();

    for (int i = 0; i < 100; ++i) {
        list->add(i);
    }

    list->remove(99);

    for (int i = 0; i < list->size(); ++i) {
        LOGD("arr factor:%d", list->get(i));
    }

    jintArray arr = env->NewIntArray(list->size());
    jint fill[list->size()];
    for (int i = 0; i < list->size(); i++) {
        fill[i] = list->get(i);
    }
    env->SetIntArrayRegion(arr, 0, list->size(), fill);
    return arr;
//---------------------ArrayList-----------------
}

Here is Add method in ArrayList :

template<class E>
void ArrayList<E>::add(E e) {
    ensureCapacityInternal(index + 1);  // Increments modCount!!
    array[index++] = e;
    LOGD("add index:%d", index);
}

When I add item at this line app crashes :

array[index++] = e;

It just happens when I call JNI method in ClickListener in Kotlin :

list.onItemClickListener = AdapterView.OnItemClickListener { p0, p1, p2, p3 ->
            val intent = Intent(this@MainActivity, DetailActivity::class.java)
            val res = getString(R.string.array_print, arrayListFromJNI().joinToString { it.toString() })
            intent.putExtra(EXTRA, res)
            startActivity(intent)
        }

Do you know how to fix it?

This is the crash log :

2020-03-24 15:56:38.254 18914-18914/com.haha.datastructuresample 

A/libc: Fatal signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0xffffffffc2000004 in tid 18914 (structuresample), pid 18914 (structuresample)
2020-03-24 17:26:56.439 31006-31006/? A/DEBUG: *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
2020-03-24 17:26:56.439 31006-31006/? A/DEBUG: Build fingerprint: 'google/walleye/walleye:10/QQ2A.200305.002/6138846:user/release-keys'
2020-03-24 17:26:56.439 31006-31006/? A/DEBUG: Revision: 'MP1'
2020-03-24 17:26:56.439 31006-31006/? A/DEBUG: ABI: 'arm64'
2020-03-24 17:26:56.440 31006-31006/? A/DEBUG: Timestamp: 2020-03-24 17:26:56+0430
2020-03-24 17:26:56.440 31006-31006/? A/DEBUG: pid: 30948, tid: 30948, name: structuresample  >>> com.haha.datastructuresample <<<
2020-03-24 17:26:56.440 31006-31006/? A/DEBUG: uid: 10283
2020-03-24 17:26:56.440 31006-31006/? A/DEBUG: signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0xffffffffc2000004
2020-03-24 17:26:56.440 31006-31006/? A/DEBUG:     x0  0000007c52191bf0  x1  0000000000000001  x2  0000007b66f309f5  x3  000000005245d020
2020-03-24 17:26:56.440 31006-31006/? A/DEBUG:     x4  0000000000000000  x5  0000007c5216ec00  x6  0000007ff77fa3f0  x7  0000007ff77f5310
2020-03-24 17:26:56.440 31006-31006/? A/DEBUG:     x8  0000000000000000  x9  0000007c52191bf0  x10 ffffffffc2000004  x11 0000000000000001
2020-03-24 17:26:56.440 31006-31006/? A/DEBUG:     x12 0000000000000000  x13 0000000000000004  x14 0000000000000006  x15 ffffffffffffffff
2020-03-24 17:26:56.440 31006-31006/? A/DEBUG:     x16 0000007b66f3ebd0  x17 0000007b66f12340  x18 0000007c52c1a000  x19 0000007c5216ec00
2020-03-24 17:26:56.440 31006-31006/? A/DEBUG:     x20 0000000000000000  x21 0000007c5216ec00  x22 0000007ff77f5610  x23 0000007b675a717f
2020-03-24 17:26:56.440 31006-31006/? A/DEBUG:     x24 0000000000000004  x25 0000007c5245d020  x26 0000007c5216ecb0  x27 0000000000000001
2020-03-24 17:26:56.440 31006-31006/? A/DEBUG:     x28 0000007ff77f53a0  x29 0000007ff77f52a0
2020-03-24 17:26:56.440 31006-31006/? A/DEBUG:     sp  0000007ff77f5270  lr  0000007b66f11884  pc  0000007b66f118ac
2020-03-24 17:26:56.632 31006-31006/? A/DEBUG: backtrace:
2020-03-24 17:26:56.632 31006-31006/? A/DEBUG:       #00 pc 00000000000118ac  /data/app/com.haha.datastructuresample-GwDwZVe9cBYUCJeWbnwXtg==/lib/arm64/libnative-lib.so (ArrayList<int>::add(int)+116) (BuildId: 654c5d2cacdf45f6d2dfd0f27cb27227cc7b303f)
2020-03-24 17:26:56.632 31006-31006/? A/DEBUG:       #01 pc 00000000000115fc  /data/app/com.haha.datastructuresample-GwDwZVe9cBYUCJeWbnwXtg==/lib/arm64/libnative-lib.so (Java_com_haha_datastructuresample_MainActivity_arrayListFromJNI+120) (BuildId: 654c5d2cacdf45f6d2dfd0f27cb27227cc7b303f)
2020-03-24 17:26:56.632 31006-31006/? A/DEBUG:       #02 pc 000000000013f350  /apex/com.android.runtime/lib64/libart.so (art_quick_generic_jni_trampoline+144) (BuildId: 62f6757870ddffe01b8bd186ef2e4a7e)
2020-03-24 17:26:56.632 31006-31006/? A/DEBUG:       #03 pc 0000000000136334  /apex/com.android.runtime/lib64/libart.so (art_quick_invoke_stub+548) (BuildId: 62f6757870ddffe01b8bd186ef2e4a7e)
2020-03-24 17:26:56.632 31006-31006/? A/DEBUG:       #04 pc 00000000001450ac  /apex/com.android.runtime/lib64/libart.so (art::ArtMethod::Invoke(art::Thread*, unsigned int*, unsigned int, art::JValue*, char const*)+244) (BuildId: 62f6757870ddffe01b8bd186ef2e4a7e)
2020-03-24 17:26:56.632 31006-31006/? A/DEBUG:       #05 pc 00000000002e2660  /apex/com.android.runtime/lib64/libart.so (art::interpreter::ArtInterpreterToCompiledCodeBridge(art::Thread*, art::ArtMethod*, art::ShadowFrame*, unsigned short, art::JValue*)+384) (BuildId: 62f6757870ddffe01b8bd186ef2e4a7e)
2020-03-24 17:26:56.632 31006-31006/? A/DEBUG:       #06 pc 00000000002dd6ec  /apex/com.android.runtime/lib64/libart.so (bool art::interpreter::DoCall<false, false>(art::ArtMethod*, art::Thread*, art::ShadowFrame&, art::Instruction const*, unsigned short, art::JValue*)+900) (BuildId: 62f6757870ddffe01b8bd186ef2e4a7e)
2020-03-24 17:26:56.632 31006-31006/? A/DEBUG:       #07 pc 00000000005a27b8  /apex/com.android.runtime/lib64/libart.so (MterpInvokeDirect+400) (BuildId: 62f6757870ddffe01b8bd186ef2e4a7e)
2020-03-24 17:26:56.632 31006-31006/? A/DEBUG:       #08 pc 0000000000130914  /apex/com.android.runtime/lib64/libart.so (mterp_op_invoke_direct+20) (BuildId: 62f6757870ddffe01b8bd186ef2e4a7e)
2020-03-24 17:26:56.632 31006-31006/? A/DEBUG:       #09 pc 0000000000155f84  [anon:dalvik-classes.dex extracted in memory from /data/app/com.haha.datastructuresample-GwDwZVe9cBYUCJeWbnwXtg==/base.apk] (com.haha.datastructuresample.MainActivity.access$arrayListFromJNI)
2020-03-24 17:26:56.632 31006-31006/? A/DEBUG:       #10 pc 00000000005a32c0  /apex/com.android.runtime/lib64/libart.so (MterpInvokeStatic+1136) (BuildId: 62f6757870ddffe01b8bd186ef2e4a7e)
2020-03-24 17:26:56.632 31006-31006/? A/DEBUG:       #11 pc 0000000000130994  /apex/com.android.runtime/lib64/libart.so (mterp_op_invoke_static+20) (BuildId: 62f6757870ddffe01b8bd186ef2e4a7e)
2020-03-24 17:26:56.632 31006-31006/? A/DEBUG:       #12 pc 0000000000155ebe  [anon:dalvik-classes.dex extracted in memory from /data/app/com.haha.datastructuresample-GwDwZVe9cBYUCJeWbnwXtg==/base.apk] (com.haha.datastructuresample.MainActivity$onCreate$1.onItemClick+34)
2020-03-24 17:26:56.632 31006-31006/? A/DEBUG:       #13 pc 00000000005a4fe0  /apex/com.android.runtime/lib64/libart.so (MterpInvokeInterfaceRange+1376) (BuildId: 62f6757870ddffe01b8bd186ef2e4a7e)
2020-03-24 17:26:56.632 31006-31006/? A/DEBUG:       #14 pc 0000000000130d14  /apex/com.android.runtime/lib64/libart.so (mterp_op_invoke_interface_range+20) (BuildId: 62f6757870ddffe01b8bd186ef2e4a7e)
2020-03-24 17:26:56.632 31006-31006/? A/DEBUG:       #15 pc 000000000021513c  /system/framework/framework.jar (android.widget.AdapterView.performItemClick+28)
2020-03-24 17:26:56.632 31006-31006/? A/DEBUG:       #16 pc 00000000005a4610  /apex/com.android.runtime/lib64/libart.so (MterpInvokeSuperRange+1936) (BuildId: 62f6757870ddffe01b8bd186ef2e4a7e)
2020-03-24 17:26:56.632 31006-31006/? A/DEBUG:       #17 pc 0000000000130b94  /apex/com.android.runtime/lib64/libart.so (mterp_op_invoke_super_range+20) (BuildId: 62f6757870ddffe01b8bd186ef2e4a7e)
2020-03-24 17:26:56.632 31006-31006/? A/DEBUG:       #18 pc 0000000000205f08  /system/framework/framework.jar (android.widget.AbsListView.performItemClick+384)
2020-03-24 17:26:56.632 31006-31006/? A/DEBUG:       #19 pc 00000000005a0730  /apex/com.android.runtime/lib64/libart.so (MterpInvokeVirtual+1432) (BuildId: 62f6757870ddffe01b8bd186ef2e4a7e)
2020-03-24 17:26:56.632 31006-31006/? A/DEBUG:       #20 pc 0000000000130814  /apex/com.android.runtime/lib64/libart.so (mterp_op_invoke_virtual+20) (BuildId: 62f6757870ddffe01b8bd186ef2e4a7e)
2020-03-24 17:26:56.632 31006-31006/? A/DEBUG:       #21 pc 0000000000203190  /system/framework/framework.jar (android.widget.AbsListView$PerformClick.run+120)
2020-03-24 17:26:56.632 31006-31006/? A/DEBUG:       #22 pc 00000000005a0730  /apex/com.android.runtime/lib64/libart.so (MterpInvokeVirtual+1432) (BuildId: 62f6757870ddffe01b8bd186ef2e4a7e)
2020-03-24 17:26:56.632 31006-31006/? A/DEBUG:       #23 pc 0000000000130814  /apex/com.android.runtime/lib64/libart.so (mterp_op_invoke_virtual+20) (BuildId: 62f6757870ddffe01b8bd186ef2e4a7e)
2020-03-24 17:26:56.632 31006-31006/? A/DEBUG:       #24 pc 0000000000209940  /system/framework/framework.jar (android.widget.AbsListView.onTouchUp+748)
2020-03-24 17:26:56.632 31006-31006/? A/DEBUG:       #25 pc 00000000005a2ab8  /apex/com.android.runtime/lib64/libart.so (MterpInvokeDirect+1168) (BuildId: 62f6757870ddffe01b8bd186ef2e4a7e)
2020-03-24 17:26:56.632 31006-3100

Solution

The problem is not in the JNI part at all, but in your ArrayList code: constructors should always fill out every field. The reason your code crashes there is because array is very probably random heap memory instead of NULL.

You need to make at least the following modifications to make your calling code not crash:

template<class E>
ArrayList<E>::ArrayList() 
  : array(nullptr), length(0) {
}

template<class E>
ArrayList<E>::ArrayList(int len) 
  : length(len) {
    array = len > 0 ? new E[len] : nullptr;
}

template<class E>
ArrayList<E>::~ArrayList() {
  delete[] array;
}

and you should definitely be compliant to the rule of three/five by overriding the copy constructor and assignment operator.

Answered By – Botje

Answer Checked By – David Goodson (Easybugfix Volunteer)

Leave a Reply

(*) Required, Your email will not be published