Mobile Development 18 min read

Understanding and Analyzing Native Crashes (NE) in Android Development

The article explains Android native crashes (NE) by describing .so file composition, the need for un‑stripped libraries, how to view and generate stripped/un‑stripped binaries, and detailed workflows using ndk‑stack, DropBox, BreakPad, objdump, addr2line, and minidump_stackwalk to reconstruct stack traces and pinpoint source lines.

vivo Internet Technology
vivo Internet Technology
vivo Internet Technology
Understanding and Analyzing Native Crashes (NE) in Android Development

In Android development, Native Crashes (NE), also known as NativeCrash, occur when C/C++ code crashes at runtime. Unlike Java exceptions, NE logs are not directly readable in Logcat and require symbol information from the original un‑stripped .so libraries to reconstruct stack traces.

1. NE Overview

NE is generated by native code (C/C++) and cannot be interpreted without the debug symbols (symbol table) embedded in an un‑stripped .so . The un‑stripped library contains a mapping of method names to their addresses, similar to a Java ProGuard mapping file. If the .so has been stripped, the debug information is removed, making stack reconstruction impossible.

1.1 .so composition

A complete .so consists of compiled C code plus debug information. Debug information creates a symbol table that maps method names to their relative addresses. Un‑stripped .so files are larger; after a strip operation the size shrinks because the debug section is removed.

Typical size comparison (before/after strip) is shown in the original article.

1.2 Viewing .so status

On macOS or Linux you can use the file command to see whether a library is stripped:

file libbreakpad-core-s.so
libbreakpad-core-s.so: *******, BuildID[sha1]=..., stripped
file libbreakpad-core.so
libbreakpad-core.so: ******, BuildID[sha1]=..., with debug_info, not stripped

If you are on Windows, the article suggests installing a Linux subsystem to run the same command.

1.3 Obtaining stripped and un‑stripped .so files in Android Studio

When building with CMake, Android Studio outputs both versions:

Un‑stripped path: build/intermediates/transforms/mergeJniLibs

Stripped path: build/intermediates/transforms/stripDebugSymbol

Alternatively, you can manually strip a library using the NDK tool aarch64-linux-android-strip (or the arm variant). The tool resides in the NDK toolchains directory, e.g.:

/Users/njvivo/Library/Android/sdk/ndk/21.3.6528147/toolchains/aarch64-linux-android-4.9/prebuilt/darwin-x86_64/bin/aarch64-linux-android-strip

Command to strip a library:

aarch64-linux-android-strip --strip-all libbreakpad-core.so

When using CMake you can add -s to the release flags to produce a stripped library automatically:

# set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -s")
# set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -s")

For mk files you can add the visibility flag:

-fvisibility=hidden

2. NE Capture and Analysis

2.1 Logcat capture with ndk‑stack

The NDK provides ndk-stack , which reads raw native crash logs from Logcat and translates them using the symbol table.

Typical usage (replace /path/to/ndk-stack and /path/to/lib.so with your actual paths):

adb shell logcat | /path/to/ndk-stack -sym /path/to/libbreakpad-core.so

Sample output:

***** Crash dump: *****
Build fingerprint: 'vivo/PD1809/...'
#00 0x00000000000161a0 /data/app/.../lib/arm64/libbreakpad-core.so (Java_com_online_breakpad_BreakpadInit_nUpdateLaunchInfo+16)
#01 0x00000000000090cc /data/app/.../oat/arm64/base.odex (offset 0x9000)
Crash dump is completed

ndk-stack internally uses addr2line to resolve addresses.

2.2 DropBox log analysis (system apps only)

System apps can retrieve native crash logs from the DropBox service. The logs can be fed to ndk-stack or to a Python analyzer to obtain stack traces.

Example command:

ndk-stack -sym /Users/njvivo/Desktop/NE-dump [email protected]

Result shows the crash location in breakpad.cpp:111 .

2.3 BreakPad capture (all apps)

BreakPad is an open‑source crash‑reporting library. It generates a minidump file ( .dmp ) and provides two auxiliary tools:

Symbol table extractor (from the .so )

Stack‑walk tool ( minidump_stackwalk ) to convert a minidump into a readable stack trace.

The minidump_stackwalk binary is bundled with Android Studio:

/Applications/Android Studio.app/Contents/bin/lldb/bin/minidump_stackwalk

Typical workflow:

Collect the .dmp generated by BreakPad.

Run minidump_stackwalk crash.dmp > crashLog.txt to produce a readable log.

Use addr2line (or the combined tool) to map addresses to source lines, e.g.:

aarch64-linux-android-addr2line -f -C -e libbreakpad-core.so 0x161a0

Output:

Crash()
/Users/njvivo/Documents/project/Breakpad/breakpad.cpp:111

Sample source snippet that triggers the crash (shown in the article):

void Crash() {
    volatile int *a = (int *)(NULL);
    *a = 1; // line 111
}

extern "C" JNIEXPORT void JNICALL Java_com_online_breakpad_BreakpadInit_nUpdateLaunchInfo(JNIEnv *env, jobject instance, jstring mLaunchInfoStr_) {
    DO_TRY {
        Crash();
        const char *mLaunchInfoStr = env->GetStringUTFChars(mLaunchInfoStr_, 0);
        launch_info = (char *)mLaunchInfoStr;
    } DO_CATCH("updateLaunchInfo");
}

3. Extracting the .so Symbol Table

NDK provides objdump to dump the symbol table:

aarch64-linux-android-objdump -S libbreakpad-core.so > breakpad.asm

The resulting .asm file contains the mapping of addresses to function names, which can be combined with logcat output to resolve the crash location.

Google also offers a Python analyzer that takes an .asm file and a logcat file to produce a stack trace:

python parse_stack.py

4. Summary

The article provides a complete guide to understanding Android native crashes, from the structure of .so files and the importance of keeping un‑stripped libraries, to various capture methods (Logcat + ndk‑stack, DropBox, BreakPad) and the tools needed to extract and analyze symbol information (file, strip, objdump, addr2line, minidump_stackwalk). Following these steps enables developers to locate the exact source line of a native crash and fix the underlying issue.

debuggingAndroidBreakpadNative CrashNDKsosymbol table
vivo Internet Technology
Written by

vivo Internet Technology

Sharing practical vivo Internet technology insights and salon events, plus the latest industry news and hot conferences.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.