std::exception SIGSEGV на Huawei JNI

после того, как я обновил свой проект Android-JNI до cmake buildsystem, я всегда получаю сбой (SIGSEGV), когда мой бэкэнд c++ выдает исключение std::. Это происходит только на телефонах Huawei.

У меня не получилось пересобрать задачу на минимальном примере.

Вот характеристики здания:

  • Инструменты сборки Android SDK: 25.0.2, 26.0.2
  • Инструменты платформы Android SDK: 26.0.1
  • Инструменты SDK для Android: 26.1.1
  • CMake: 3.6.4111459
  • NDK: 15.2.4203891

Gradle: (также пытался использовать '-DANDROID_TOOLCHAIN=gcc')

externalNativeBuild {
    cmake {
        cppFlags "-frtti -fexceptions -pthread -v -std=c++11"
        arguments '-DANDROID_PLATFORM=android-9', '-DANDROID_TOOLCHAIN=clang', '-DANDROID_STL=gnustl_shared'
    }
}
ndk {
    abiFilters 'armeabi'
}

Сигнал: SIGSEGV (сигнал SIGSEGV: неверный адрес (адрес ошибки: 0x7))

Со следующей трассировкой стека:

unw_get_reg
_Unwind_VRS_Interpret
__gnu_Unwind_RaiseException
___Unwind_RaiseException
__cxxabiv1::__cxa_throw(void *, std::type_info *, void (*)(void *))
testTryCatch()
Java_de_company_project_wrapper_SystemWrapper_startApplication
art_quick_generic_jni_trampoline
art_quick_invoke_stub_internal
art_quick_invoke_stub

Это буквально первая функция, которая вызывается в моем бэкэнде:

#include <exception>
#include <android/log.h>

void testTryCatch() {
    try {
        throw std::exception();
    }catch(std::exception &e){
        __android_log_write(ANDROID_LOG_INFO, "testException", "done");
    }
}

JNIEXPORT void JNICALL
Java_de_company_project_wrapper_SystemWrapper_startApplication(JNIEnv *env, 
    jclass obj)
{
    testTryCatch();
}

Это происходит в большом проекте, библиотека c/c++ занимает около 16 МБ. Есть и другие библиотеки, статически связанные (OpenSSL/FFmpeg/opus/zip).

Итак, мой вопрос заключается в том, как решить эту проблему и почему библиотека аварийно завершает работу при выдаче исключения std::, появляется только на телефонах Huawei (после обновления до системы сборки cmake)?

(кстати: избавляться от всех исключений std:: не очень хорошая идея)


person Da Maex    schedule 23.10.2017    source источник
comment
Судя по трассировке стека, первая функция, которую вы показали, не имеет к этому никакого отношения — разные имена функций, тот же класс исключений. Вызывается ли этот код или он падает раньше? Может быть, он падает при инициализации библиотеки? Если да, можете ли вы продолжить удаление библиотек и посмотреть, какая из них вызывает ошибку?   -  person hauron    schedule 23.10.2017
comment
Поменял стек! Сбой появляется при броске внутри метода testTryCatch(). Сейчас я удаляю библиотеки по одному, это занимает много времени. Доложит.   -  person Da Maex    schedule 23.10.2017
comment
Я удалил все внешние библиотеки, но проблема осталась. Я сейчас ищу в источниках С++, если где-то появляется повреждение памяти. Еще бы: почему только на Huawei?!?   -  person Da Maex    schedule 23.10.2017
comment
По крайней мере, теперь вы знаете, что это не дополнительные библиотеки. Я бы проверил системные. См. здесь: developer.android.com/ndk/guides/cpp-support.html Может быть связано с: '-DANDROID_STL=gnustl_shared' - возможно, вам нужна другая реализация?   -  person hauron    schedule 24.10.2017
comment
Проблема действительно заключалась в gnustl_shared, измененном на c++_shared, и он работает.   -  person Da Maex    schedule 25.10.2017


Ответы (2)


Я нашел решение своей проблемы с помощью, увиденной в комментариях. Похоже, что у Huawei возникают проблемы с библиотекой gnustl_shared, когда сама библиотека становится слишком большой. Поэтому я изменил свой externalNativeBuild на c++_shared соответственно.

externalNativeBuild {
    cmake {
        cppFlags "-pthread -v -std=c++11"
        arguments '-DANDROID_PLATFORM=android-9', '-DANDROID_CPP_FEATURES=rtti exceptions',
                  '-DANDROID_STL=c++_shared', '-DANDROID_TOOLCHAIN=clang'
    }
}
person Da Maex    schedule 25.10.2017
comment
У меня была точно такая же проблема, но при использовании вашего решения экран становится черным, а приложение зависает и даже не вылетает. Можете ли вы предложить какое-либо другое решение? - person user3406222; 18.02.2019
comment
Можете ли вы уточнить версии, которые вы используете (платформа, набор инструментов, SDK, NDK, CMake), и это только на устройствах Huawei? - person Da Maex; 26.02.2019

Я встречаю ту же проблему, стек выглядит так:

backtrace:
  #00 pc 00056dfe  /apex/com.android.runtime/lib/bionic/libc.so (abort+166) (BuildId: b1803e2c54cf63f48664b8839ccf313b)
  #01 pc 00014daf  /data/app/org.swig.cppexception-TAwOh_fwpqXbW-uy7twUGg==/lib/arm/libnative-lib.so (BuildId: 030a2de7aefd84866dea1b48f592d7fdad70db2d)
  #02 pc 00014851  /data/app/org.swig.cppexception-TAwOh_fwpqXbW-uy7twUGg==/lib/arm/libnative-lib.so (BuildId: 030a2de7aefd84866dea1b48f592d7fdad70db2d)
  #03 pc 000146a9  /data/app/org.swig.cppexception-TAwOh_fwpqXbW-uy7twUGg==/lib/arm/libnative-lib.so (__gxx_personality_v0+100) (BuildId: 030a2de7aefd84866dea1b48f592d7fdad70db2d)
  #04 pc 001bd04c  /data/app/org.swig.cppexception-TAwOh_fwpqXbW-uy7twUGg==/lib/arm/libffmpeg.so (__gnu_Unwind_RaiseException+108)
  #05 pc 001bdb90  /data/app/org.swig.cppexception-TAwOh_fwpqXbW-uy7twUGg==/lib/arm/libffmpeg.so (___Unwind_RaiseException+20)

после поиска в мире я обнаружил, что это вызвано исключением cpp throw. Я поймал исключение cpp, но оно все равно разбилось.

'-DANDROID_STL=c++_static' -> '-DANDROID_STL=c++_shared'

вышеуказанная модификация спасла меня. теперь можно перехватить исключение cpp.
Но я все же нашел, кто это вызвал?

person bluesky    schedule 11.12.2020
comment
Это также на устройствах Huawei? - person Da Maex; 11.12.2020
comment
Нет. У каждого Android-устройства oppo/xiaomi также есть проблема. - person bluesky; 15.12.2020