NDK Issue: сбой на 32-битной, несоответствие на 64-битной

У меня есть эта проблема с моим кодом C++. Это поиск по графику, и он использует несколько потоков. Потоки не зависят друг от друга, у каждого из них разные параметры поиска, но они будут обращаться только к исходному графу с правом чтения, записывать только массив результатов, читать и записывать очередь заданий.

На 32-битных устройствах: arm или x86 при новом вызове происходит случайный сбой. Будь это struct, class, std::vector<> или когда std::vector<> придется перераспределить память, чтобы учесть большую емкость.

Вот пример:

********** Crash dump: **********
Build fingerprint: 'google/hammerhead/hammerhead:6.0.1/M4B30Z/3437181:user/release-keys'
pid: 2341, tid: 2356, name: roidJUnitRunner  >>> com.transit102.nativesearchengine.test <<<
signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0xdeadcab1
Stack frame 03-19 20:44:41.379  2142  2142 F DEBUG   :     #00 pc 00016fce  /data/app/com.transit102.nativesearchengine.test-1/lib/arm/libtransit-searchengine.so: Routine __gabixx::__default_terminate() at /usr/local/google/buildbot/src/android/ndk-r14-release/out/build/tmp/build-22588/build-stlport/ndk/sources/cxx-stl/gabi++/src/terminate.cc:72
Stack frame 03-19 20:44:41.379  2142  2142 F DEBUG   :     #01 pc 00016fe3  /data/app/com.transit102.nativesearchengine.test-1/lib/arm/libtransit-searchengine.so: Routine __gabixx::__terminate(void (*)()) at /usr/local/google/buildbot/src/android/ndk-r14-release/out/build/tmp/build-22588/build-stlport/ndk/sources/cxx-stl/gabi++/src/terminate.cc:84
Stack frame 03-19 20:44:41.379  2142  2142 F DEBUG   :     #02 pc 00016fb9  /data/app/com.transit102.nativesearchengine.test-1/lib/arm/libtransit-searchengine.so: Routine std::terminate() at /usr/local/google/buildbot/src/android/ndk-r14-release/out/build/tmp/build-22588/build-stlport/ndk/sources/cxx-stl/gabi++/src/terminate.cc:110 (discriminator 1)
Stack frame 03-19 20:44:41.379  2142  2142 F DEBUG   :     #03 pc 00016745  /data/app/com.transit102.nativesearchengine.test-1/lib/arm/libtransit-searchengine.so: Routine __cxxabiv1::call_terminate(_Unwind_Control_Block*) at /usr/local/google/buildbot/src/android/ndk-r14-release/out/build/tmp/build-22588/build-stlport/ndk/sources/cxx-stl/gabi++/src/helper_func_internal.cc:54
Stack frame 03-19 20:44:41.379  2142  2142 F DEBUG   :     #04 pc 000162dd  /data/app/com.transit102.nativesearchengine.test-1/lib/arm/libtransit-searchengine.so: Routine (anonymous namespace)::throwException(__cxxabiv1::__cxa_exception*) at /usr/local/google/buildbot/src/android/ndk-r14-release/out/build/tmp/build-22588/build-stlport/ndk/sources/cxx-stl/gabi++/src/cxxabi.cc:271
Stack frame 03-19 20:44:41.379  2142  2142 F DEBUG   :     #05 pc 000162a3  /data/app/com.transit102.nativesearchengine.test-1/lib/arm/libtransit-searchengine.so: Routine __cxa_throw at /usr/local/google/buildbot/src/android/ndk-r14-release/out/build/tmp/build-22588/build-stlport/ndk/sources/cxx-stl/gabi++/src/cxxabi.cc:335
Stack frame 03-19 20:44:41.379  2142  2142 F DEBUG   :     #06 pc 00016cab  /data/app/com.transit102.nativesearchengine.test-1/lib/arm/libtransit-searchengine.so (_Znwj+70): Routine operator new(unsigned int) at /usr/local/google/buildbot/src/android/ndk-r14-release/out/build/tmp/build-22588/build-stlport/ndk/sources/cxx-stl/gabi++/src/new.cc:105
Stack frame 03-19 20:44:41.379  2142  2142 F DEBUG   :     #07 pc 0000e0a5  /data/app/com.transit102.nativesearchengine.test-1/lib/arm/libtransit-searchengine.so (_ZSt9__stl_newj+12): Routine std::__stl_new(unsigned int) at C:/Users/auras/Android/sdk/ndk-bundle/sources/cxx-stl/stlport/stlport\stl/_new.h:134
Stack frame 03-19 20:44:41.379  2142  2142 F DEBUG   :     #08 pc 0000e081  /data/app/com.transit102.nativesearchengine.test-1/lib/arm/libtransit-searchengine.so (_ZNSt12__node_alloc8allocateERj+24): Routine std::__node_alloc::allocate(unsigned int&) at C:/Users/auras/Android/sdk/ndk-bundle/sources/cxx-stl/stlport/stlport\stl/_alloc.h:158 (discriminator 1)
Stack frame 03-19 20:44:41.379  2142  2142 F DEBUG   :     #09 pc 0000e6f3  /data/app/com.transit102.nativesearchengine.test-1/lib/arm/libtransit-searchengine.so (_ZNSaIjE11_M_allocateEjRj+102): Routine std::allocator<unsigned int>::_M_allocate(unsigned int, unsigned int&) at C:/Users/auras/Android/sdk/ndk-bundle/sources/cxx-stl/stlport/stlport\stl/_alloc.h:348
Stack frame 03-19 20:44:41.379  2142  2142 F DEBUG   :     #10 pc 0000e685  /data/app/com.transit102.nativesearchengine.test-1/lib/arm/libtransit-searchengine.so (_ZNSt4priv17_STLP_alloc_proxyIPjjSaIjEE8allocateEjRjRKSt11__true_type+40): Routine std::priv::_STLP_alloc_proxy<unsigned int*, unsigned int, std::allocator<unsigned int> >::allocate(unsigned int, unsigned int&, std::__true_type const&) at C:/Users/auras/Android/sdk/ndk-bundle/sources/cxx-stl/stlport/stlport\stl/_alloc.h:551
Stack frame 03-19 20:44:41.379  2142  2142 F DEBUG   :     #11 pc 0000e4f1  /data/app/com.transit102.nativesearchengine.test-1/lib/arm/libtransit-searchengine.so (_ZNSt4priv17_STLP_alloc_proxyIPjjSaIjEE8allocateEjRj+48): Routine std::priv::_STLP_alloc_proxy<unsigned int*, unsigned int, std::allocator<unsigned int> >::allocate(unsigned int, unsigned int&) at C:/Users/auras/Android/sdk/ndk-bundle/sources/cxx-stl/stlport/stlport\stl/_alloc.h:531
Stack frame 03-19 20:44:41.379  2142  2142 F DEBUG   :     #12 pc 00014c69  /data/app/com.transit102.nativesearchengine.test-1/lib/arm/libtransit-searchengine.so (_ZNSt4priv12_Vector_baseIjSaIjEEC2EjRKS1_+80): Routine _Vector_base at C:/Users/auras/Android/sdk/ndk-bundle/sources/cxx-stl/stlport/stlport\stl/_vector.h:71
Stack frame 03-19 20:44:41.379  2142  2142 F DEBUG   :     #13 pc 0001299f  /data/app/com.transit102.nativesearchengine.test-1/lib/arm/libtransit-searchengine.so (_ZNSt6vectorIjSaIjEEC2ERKS1_+66): Routine vector at C:/Users/auras/Android/sdk/ndk-bundle/sources/cxx-stl/stlport/stlport\stl/_vector.h:247
Stack frame 03-19 20:44:41.379  2142  2142 F DEBUG   :     #14 pc 0000ff61  /data/app/com.transit102.nativesearchengine.test-1/lib/arm/libtransit-searchengine.so (_ZN10transit10215NewSearchEngine7PushJobEjPSt6vectorIjSaIjEEjS4_jS4_hPS1_IPNS_7JourneyESaIS6_EE+240): Routine transit102::NewSearchEngine::PushJob(unsigned int, std::vector<unsigned int, std::allocator<unsigned int> >*, unsigned int, std::vector<unsigned int, std::allocator<unsigned int> >*, unsigned int, std::vector<unsigned int, std::allocator<unsigned int> >*, unsigned char, std::vector<transit102::Journey*, std::allocator<transit102::Journey*> >*) at C:\Users\auras\AndroidStudioProjects\Transit102\nativesearchengine\src\main\jni/newsearchengine.cpp:965

Общий знаменатель для аварий всегда

Stack frame 03-19 20:44:41.379  2142  2142 F DEBUG   :     #06 pc 00016cab  /data/app/com.transit102.nativesearchengine.test-1/lib/arm/libtransit-searchengine.so (_Znwj+70): Routine operator new(unsigned int) at /usr/local/google/buildbot/src/android/ndk-r14-release/out/build/tmp/build-22588/build-stlport/ndk/sources/cxx-stl/gabi++/src/new.cc:105

На 64-битных устройствах: arm или x64 он никогда не падает, хотя я получаю разные результаты при каждом запуске теста, чего не было до рефакторинга кода.

Моя главная проблема - сбой, я могу отлаживать после этого, если это все еще происходит, почему я получаю разные результаты для каждого запуска.

РЕДАКТИРОВАТЬ:

Я перенес код в Visual Studio 2015, и код никогда не падает на 32-разрядной или 64-разрядной версии, и нет утечек памяти.

CMakeLists.txt:

# Sets the minimum version of CMake required to build your native library.
# This ensures that a certain set of CMake features is available to
# your build.

cmake_minimum_required(VERSION 3.4.1)

# Specifies a library name, specifies whether the library is STATIC or
# SHARED, and provides relative paths to the source code. You can
# define multiple libraries by adding multiple add.library() commands,
# and CMake builds them for you. When you build your app, Gradle
# automatically packages shared libraries with your APK.

add_library( # Specifies the name of the library.
             transit-searchengine

             # Sets the library as a shared library.
             SHARED

             # Provides a relative path to your source file(s).
             src/main/jni/android_osutils.cpp
             src/main/jni/graph.cpp
             src/main/jni/journey.cpp
             src/main/jni/newsearchengine.cpp
             src/main/jni/searchengine.cpp
             src/main/jni/jniwrapper.cpp )

# Specifies a path to native header files.
include_directories(src/main/jni/)

find_library( # Defines the name of the path variable that stores the
              # location of the NDK library.
              log-lib

              # Specifies the name of the NDK library that
              # CMake needs to locate.
              log )

# Links your native library against one or more other native libraries.
target_link_libraries( # Specifies the target library.
                       transit-searchengine

                       # Links the log library to the target library.
                       ${log-lib} )

build.gradle:

android {
    compileSdkVersion rootProject.versionAndroidSdk
    buildToolsVersion rootProject.versionBuildTools

    defaultConfig {
        minSdkVersion rootProject.versionMinAndroidSdk
        targetSdkVersion rootProject.versionAndroidSdk
        versionCode 1
        versionName "1.0"

        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"

        externalNativeBuild {
            cmake {
                // Passes optional arguments to CMake.
                arguments "-DANDROID_TOOLCHAIN=clang", "-DANDROID_STL=stlport_static", "-DANDROID_UNIFIED_HEADERS=ON"
                cppFlags "-std=c++11"
            }
        }
    }
    buildTypes {
        debug {
            minifyEnabled false
            shrinkResources false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            ndk {
                debuggable true
            }
        }
        release {
            minifyEnabled false
            shrinkResources false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            ndk {
                debuggable true
            }
        }
    }

    externalNativeBuild {
        cmake {
            path 'CMakeLists.txt'
        }
    }
}

1 ответ

Я посмотрел на исходное местоположение, упомянутое в сбое, для вашей версии NDK (r14): new.cc.

Судя по всему, newпытался malloc, который потерпел неудачу, вернувnullptrзатем попытался получить токnew_handler, который потерпел неудачу, потому что один не был установлен, поэтому он был вынужден взорваться.

Кажется, вы просто исчерпали память на своем 32-битном устройстве Android. Если вы используете версию Android ниже 4.4, то вашему приложению может быть запрещено выделять больше виртуальной памяти, чем физической памяти (Android < 4.4 не использует никакой подкачки памяти).

  • После 4.4 они добавили zRAM (сжатие страниц), что может помочь: грязные страницы могут быть сжаты, чтобы занять меньше оперативной памяти. Если можете, попробуйте запустить на 32-битном устройстве с 4.4+.
  • Или на 32-битном устройстве с большей физической памятью.
Другие вопросы по тегам