This document shows you how to enable special debugging tools when using
AGDE. These tools can help with hard-to-diagnose memory
corruption and overwrite errors.

## HWAddress Sanitizer and Address Sanitizer

[HWAddress Sanitizer](https://developer.android.com/ndk/guides/hwasan) (HWASan) and [Address
Sanitizer](https://developer.android.com/ndk/guides/asan) (ASan) are memory corruption debugging tools that
help with debugging memory corruption and overwrite errors, such as the
following:

- Stack buffer overflows and underflows
- Heap buffer overflows and underflows
- Stack use outside of its scope
- Double free and wild free errors
- Stack use after return (HWASan only)

We recommend enabling HWASan or ASan only when you're debugging an issue or as
part of automated testing. While these tools are performant, their use does
incur a penalty.

### Runtime behavior

When enabled, both HWASan and ASan automatically check for memory corruption in
your app.

If a memory error is detected, the app crashes with a `SIGBART` (signal abort)
error and prints a detailed message to logcat. A copy of the message is
also written to a file under `/data/tombstones`.

The error message looks similar to the following:  

    ERROR: HWAddressSanitizer: tag-mismatch on address 0x0042a0826510 at pc 0x007b24d90a0c
    WRITE of size 1 at 0x0042a0826510 tags: 32/3d (ptr/mem) in thread T0
        #0 0x7b24d90a08  (/data/app/com.example.hellohwasan-eRpO2UhYylZaW0P_E0z7vA==/lib/arm64/libnative-lib.so+0x2a08)
        #1 0x7b8f1e4ccc  (/apex/com.android.art/lib64/libart.so+0x198ccc)
        #2 0x7b8f1db364  (/apex/com.android.art/lib64/libart.so+0x18f364)
        #3 0x7b8f2ad8d4  (/apex/com.android.art/lib64/libart.so+0x2618d4)

    0x0042a0826510 is located 0 bytes to the right of 16-byte region [0x0042a0826500,0x0042a0826510)
    allocated here:
        #0 0x7b92a322bc  (/apex/com.android.runtime/lib64/bionic/libclang_rt.hwasan-aarch64-android.so+0x212bc)
        #1 0x7b24d909e0  (/data/app/com.example.hellohwasan-eRpO2UhYylZaW0P_E0z7vA==/lib/arm64/libnative-lib.so+0x29e0)
        #2 0x7b8f1e4ccc  (/apex/com.android.art/lib64/libart.so+0x198ccc)

## Prerequisites

| **Note:** Use HWASan rather than ASan, as HWASan is faster and has lower memory overhead. However, HWASan has some additional requirements.

### HWASan requirements

To use HWASan:

- You must use AGDE 24.1.99 or higher.
- The app must be built using NDK 26 or higher.
- The app must be built with target SDK 34 or higher.
- The target must be an `arm64-v8a` device running Android 14 (API level 34) or higher.

### Use the shared C++ Standard Library in your project

Due to a known issue, ASan is incompatible with C++ exception handling when
using `libc++_static`. This issue is not seen when using `libc++_shared`.

HWASan has its own implementation of operators `new` and `delete`, which can't
be used if the standard library is statically linked into the project.
| **Caution:** You must use the shared version of the Standard Library in your project when using these features.

To change this setting, see the [Linking the C++ Standard Library](https://developer.android.com/games/agde/address-sanitizer#linking-c++)
section of this document.
| **Note:** If you've enabled ASan and haven't enabled the shared C++ library, you'll encounter a build error.

### Enable Frame Pointer generation

HWASan and ASan use a fast frame pointer-based unwinder to generate stack trace
information for memory allocation and deallocation events. This means that you
must enable frame pointer generation in your C++ compiler settings to use these
features. That is, you need to disable frame pointer omission optimization.

To change this setting, see the [Enabling Frame Pointer
generation](https://developer.android.com/games/agde/address-sanitizer#enabling-frame) section of this document.
| **Note:** If you've enabled ASan and haven't enabled Frame Pointer generation, you'll encounter a build error.

## Configuring your Visual Studio project to use HWASan or ASan

### Enabling HWASan or ASan

To enable HWASan or ASan, go to **Configuration Properties \> General** in the
**Property Pages** for your project.

![The Visual Studio Solution Explorer properties menu for the current
project.](https://developer.android.com/games/agde/images/solution-explorer-project-properties-menu.png)

**Figure 1** : The project's **Properties** option in the Visual Studio Solution
Explorer window.

![The project Property Pages dialog with General properties shown, and Address
Sanitizer settings highlighted.](https://developer.android.com/games/agde/images/project-properties-asan-setting.png)

**Figure 2** : The **Address Sanitizer (ASan)** setting in the general project
properties.

To enable HWASan for your project, change the **Address Sanitizer (ASan)**
setting to
**Hardware ASan Enabled (fsanitize=hwaddress)**.

To enable ASan for your project, change the **Address Sanitizer (ASan)** setting
to **ASan Enabled (fsanitize=address)**.
| **Caution:** To avoid unnecessary overhead, remember to set the property value back to **Disabled** when you no longer need to use these tools.

### Enabling Frame Pointer generation

Frame Pointer generation is controlled by the **Omit Frame Pointer** C/C++
compiler setting and can be found in your project **Property Pages** under
**Configuration Properties \> C/C++ \> Optimization**.

![The project Property Pages dialog with C/C++ Optimization properties shown,
and Omit Frame Pointer settings
highlighted.](https://developer.android.com/games/agde/images/project-properties-cpp-frame-pointer-setting.png)

**Figure 3** : Where to find the **Omit Frame Pointer** setting.

When using HWASan or ASan, set the **Omit Frame Pointer** setting to
**No (-fno-omit-frame-pointer)**.
| **Caution:** Be sure to reset this property value back to your original setting when not using HWASan or ASan.

### Linking the C++ Standard Library in shared library mode

The linker mode setting for the C++ Standard Library can be found in your
project's **Property Pages** under **Configuration Properties \> General** , in
the **Project Defaults** section.

![The project Property Pages dialog with the General category selected, and the
Use of STL setting
highlighted.](https://developer.android.com/games/agde/images/project-properties-cpp-stl-setting.png)

**Figure 4**: Where to find linker mode setting for the C++ Standard Library.

While using HWASan or ASan, set
**Use of STL** to **Use C++ Standard Libraries (.so)** . This value links the C++
standard library into your project as a *shared library*, which is required for
HWASan and ASan to function correctly.
| **Caution:** Don't use **GNU STL** libraries here, as they are unsupported by versions 25 or higher of the NDK. For more information, see the NDK documentation on [C++ Support](https://developer.android.com/ndk/guides/cpp-support).
| **Note:** Remember to restore these settings back to their original values once you're done using HWASan or ASan.

### Creating a Build Configuration for Address Sanitizer use

If you prefer to use HWASan or ASan *transiently*, you might not want to create
a new build configuration solely for their use. This might be the case if your
project is small, you're exploring the feature, or in response to a problem you
discover during testing.

However, if you find it useful and plan to use it regularly, you might consider
creating a new build configuration for HWASan or ASan as demonstrated in the
[Teapot sample](https://developer.android.com/games/agde/samples#teapot). You might do this if, for example,
you regularly run Address Sanitizer as part of your unit tests, or during
overnight smoke-tests of your game.

Creating a separate build configuration might be especially useful if you have a
large project which consumes a large number of different third party libraries
where you normally statically link them with the C++ standard library. Dedicated
build configurations can help to ensure that your project settings remain
accurate at all times.

To create a build configuration, from your project's **Property Pages** , click
the
**Configuration Manager...** button, and then open the
**Active solution configuration** drop-down. Then selection , and
create a new build configuration with an appropriate name (for example, *HWASan
enabled*).

### Using HWASan with custom memory allocators

HWASan automatically intercepts memory allocated via `malloc` (or `new`)
so that it can inject tags into pointers and check for tag mismatches.

However, when using a custom memory allocator, HWASan is not able to
automatically intercept your custom memory allocation methods. Therefore, if you
want to use HWASan with your custom memory allocator,
instrument your memory allocator to call HWASan explicitly. This can be
done with only a few lines of code.
| **Note:** See the [PoolAllocator sample](https://developer.android.com/games/agde/samples#poolallocator) that shows how to integrate HWASan into a custom memory allocator.

#### Prerequisites

The HWASan methods you need to call are defined in this header:  

    #include "sanitizer/hwasan_interface.h"

#### Instrument your memory allocation method

1. Allocate objects at 16-byte block granularity and alignment.
   For instance, if you have a pool allocator that serves fixed-size objects of
   24-byte size, round your allocations up to 32-bytes, and
   align to 16 bytes.

2. Generate an 8-bit tag. Your tag must not use values 0-16, as those
   values are reserved for internal use.

3. Enable HWASan to start tracking the memory region with that tag:

       __hwasan_tag_memory((void*) address, tag, size);

4. Inject the tag to the top 8-bits of your pointer:

       address = __hwasan_tag_pointer((void*) address, tag);

#### Instrument your memory deallocation method

1. Reset the tag for the memory region to cause further accesses via the
   existing tagged pointers to fail:

       __hwasan_tag_memory(__hwasan_tag_pointer(ptr, 0), 0, size);

#### Working with a preallocated pool of objects

If your memory allocator preallocates objects in a pool and returns objects
back into the pool instead of actually freeing them, then your deallocation
method can directly overwrite the tag for the memory and the pointer with a new
value:  

    ```
    __hwasan_tag_memory(__hwasan_tag_pointer(ptr, 0), tag, size);
    ptr = __hwasan_tag_pointer((void*)ptr, tag);
    ```

If you use this technique, your allocation methods do not need to tag pointers
or memory blocks, but tag the pointers and memory blocks when you preallocate the objects
in your pool. See [PoolAllocator sample](https://developer.android.com/games/agde/samples#poolallocator) for
an example that uses this style.