## Debug native crashes

If you're struggling to understand a native crash dump or tombstone,[Debugging Native Android Platform Code](https://source.android.com/devices/tech/debug/index.html)is a good introduction.

For a fuller catalog of common types of crash and how to investigate them, see[Diagnosing Native Crashes](https://source.android.com/devices/tech/debug/native-crash).

The[ndk-stack](https://developer.android.com/ndk/guides/ndk-stack)tool can help symbolize your crashes. You can debug crashes in Android Studio as described in the general[Debug your app](https://developer.android.com/studio/debug)documentation. If you prefer to use the command-line,[ndk-gdb](https://developer.android.com/ndk/guides/ndk-gdb)lets you attach either`gdb`or`lldb`from your shell.

### Provide apps direct access to tombstone traces

Starting in Android 12 (API level 31), you can access your app's native crash tombstone as a[protocol buffer](https://developers.google.com/protocol-buffers/)through the[`ApplicationExitInfo.getTraceInputStream()`](https://developer.android.com/reference/android/app/ApplicationExitInfo#getTraceInputStream())method. The protocol buffer is serialized using[this schema](https://android.googlesource.com/platform/system/core/+/refs/heads/main/debuggerd/proto/tombstone.proto). Previously, the only way to get access to this information was through the[Android Debug Bridge](https://developer.android.com/studio/command-line/adb)(adb).

Here's an example of how to implement this in your app:  

    ActivityManager activityManager: ActivityManager = getSystemService(Context.ACTIVITY_SERVICE);
    MutableList<ApplicationExitInfo> exitReasons = activityManager.getHistoricalProcessExitReasons(/* packageName = */ null, /* pid = */ 0, /* maxNum = */ 5);
    for (ApplicationExitInfo aei: exitReasons) {
        if (aei.getReason() == REASON_CRASH_NATIVE) {
            // Get the tombstone input stream.
            InputStream trace = aei.getTraceInputStream();
            // The tombstone parser built with protoc uses the tombstone schema, then parses the trace.
            Tombstone tombstone = Tombstone.parseFrom(trace);
        }
    }

## Debug native memory issues

### Address Sanitizer (HWASan/ASan)

[HWAddress Sanitizer](https://developer.android.com/ndk/guides/hwasan)(HWASan) and[Address Sanitizer](https://developer.android.com/ndk/guides/asan)(ASan) are similar to Valgrind, but significantly faster and much better supported on Android.

These are your best option for debugging memory errors on Android.

### Malloc debug

See[Malloc Debug](https://android.googlesource.com/platform/bionic/+/main/libc/malloc_debug/README.md)and[Native Memory Tracking using libc Callbacks](https://android.googlesource.com/platform/bionic/+/main/libc/malloc_debug/README_api.md)for a thorough description of the C library's built-in options for debugging native memory issues.

### Malloc hooks

If you want to build your own tools, Android's libc also supports intercepting all allocation/free calls that happen during program execution. See the[malloc_hooks documentation](https://android.googlesource.com/platform/bionic/+/main/libc/malloc_hooks/README.md)for usage instructions.

### Malloc statistics

Android supports the[mallinfo(3)](http://man7.org/linux/man-pages/man3/mallinfo.3.html)and[malloc_info(3)](http://man7.org/linux/man-pages/man3/malloc_info.3.html)extensions to`<malloc.h>`.

The`malloc_info`functionality is available in Android 6.0 (Marshmallow) and higher and its XML schema is documented in Bionic's[malloc.h](https://android.googlesource.com/platform/bionic/+/main/libc/include/malloc.h)header.

## Profiling

For CPU profiling of native code, you can use[Simpleperf](https://developer.android.com/ndk/guides/simpleperf).