Reputation: 7586
I have this problem with my c++ code. It's a doing a graph search and it uses multiple threads. The threads don't depend on each other, they each have different search parameters, but will access read only the source graph, write only the results array and read and write the job queue.
On 32bit devices: arm or x86 it will crash randomly on a new call. Be it a struct
, class
, std::vector<>
or when a std::vector<>
will have to reallocate memory to allow for a larger capacity.
Here's a sample:
********** 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
The common denominator for crashes is always
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
On 64bit devices: arm or x64 it never crashes, even though I get different results every time I run the test which didn't happen before refactoring the code.
My main issue is the crashing, I can debug after that, if it still happens, why I get different results for every run.
EDIT:
I've ported the code to Visual Studio 2015 and the code never crashes on 32bit or 64bit and there are no memory leaks.
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'
}
}
}
Upvotes: 1
Views: 915
Reputation: 3716
I had a look at the source location mentioned in the crash, for your version of the NDK (r14): new.cc.
By the looks of things, new
tried malloc
, which failed, returning a nullptr
, then it tried to get the current new_handler
, which failed, because one hasn't been set, so it was forced to explode.
It seems as though you've simply exhausted the memory on your 32bit Android device. If you're running a version of Android below 4.4, then your app may not be allowed to allocate more virtual memory than there is physical memory (Android < 4.4 doesn't utilise any kind of swap memory).
Upvotes: 0