Easy debugging of Geode mods with HWASan This article provides a guide on using HWASan (Hardware-Assisted AddressSanitizer) to debug memory bugs in Geode mods on Android devices running Android 14 or later. It explains how to enable the tool by passing a cmake argument during the build process, deploy a debug launcher, and analyze resulting crash logs (tombstones) to identify issues like use-after-free errors. The guide also includes troubleshooting tips, such as disabling the crash handler and verifying that the sanitizer is properly running. Easy debugging of Geode mods with HWASan ASan and it's younger brother, HWASan are incredible tools for debugging memory integrity bugs in native applications. This guide explains how to set up HWASan for Geode mods on Android and how to analyze crashes. Requirements: Device running Android 14+, lower is possible but only with ASan, which has a slightly different way of setting up. See here https://source.android.com/docs/security/test/asan Android Studio or any other way of building the launcher Build the mod Simply pass -DANDROID SANITIZE=hwaddress as a cmake argument: sh geode build -p android64 --config Debug -- -DANDROID SANITIZE=hwaddress Build launcher Clone the launcher https://github.com/geode-sdk/android-launcher/ , and add a file app/src/main/resources/lib/arm64-v8a/wrap.sh with the following contents: sh /system/bin/sh LD HWASAN=1 exec "$@" Build a debug version and deploy it to your device. Test To see if it's working, let's add some example UB code to our mod cpp auto test = new int; delete test; volatile int test = 1; Before testing, make sure to disable the crash handler In the launcher settings, open developer settings and enter --geode:disable-crash-handler in Launch arguments. If this code does not immediately crash, ASan is likely not properly working. You can add exit as the first line after the shebang to your wrap.sh script and rebuild the launcher to see if the script is ever getting ran. If you did everything right, the game should've crashed. Tombstones are available in /data/tombstones . Make sure you pull the most recent one, because this directory includes crash dumps of all apps on your system. sh $ adb shell $ cd /data/tombstones $ ls -lt puts most recent at top $ exit $ adb pull /data/tombstones/tombstone xx ./ If the tombstone says something about seccomp disallowing syscalls, you likely pulled the wrong crashlog or did not disable the crash handler. Analyzing Here's an example of a tombstone: crDroid Version: '12.1' Build fingerprint: 'google/tegu/tegu:16/BP2A.250805.005/13691446:user/release-keys' Revision: 'MP1.0' ABI: 'arm64' Timestamp: 2026-01-12 14:05:22.951988409+0100 Process uptime: 203s Cmdline: com.geode.launcher pid: 31028, tid: 31963, name: Main com.geode.launcher <<< uid: 10637 tagged addr ctrl: 0000000000000001 PR TAGGED ADDR ENABLE pac enabled keys: 000000000000000f PR PAC APIAKEY, PR PAC APIBKEY, PR PAC APDAKEY, PR PAC APDBKEY signal 6 SIGABRT , code -1 SI QUEUE , fault addr -------- Abort message: '==31028==ERROR: HWAddressSanitizer: tag-mismatch on address 0x004649442de0 at pc 0x006d75f0f724 WRITE of size 4 at 0x004649442de0 tags: c4/aa ptr/mem in thread T48 0 0x006d75f0f724 /data/data/com.geode.launcher/files/geode/unzipped/dankmeme.globed2/dankmeme.globed2.android64.so+0x495724 BuildId: c5eada8116c0f6e8eb8a6a995810433c3dcdb594 1 0x007819bc4b9c /data/app/~~dZyWKnk3vxy emc7LuY4yA==/com.robtopx.geometryjump-6y1HhI10jOa9Pdg7lr TzQ==/split config.arm64 v8a.apk /lib/arm64-v8a/libcocos2dcpp.so+0xac9b9c BuildId: 42f8945feca43dcb3a375f99b8b68cf32456dda8 0x004649442de0,0x004649442e00 is a small unallocated heap chunk; size: 32 offset: 0 Cause: use-after-free 0x004649442de0 is located 0 bytes inside a 4-byte region 0x004649442de0,0x004649442de4 freed by thread T48 here: 0 0x00783615e57c /apex/com.android.runtime/lib64/bionic/libclang rt.hwasan-aarch64-android.so+0x2957c BuildId: 742636119ffb24484fe45c5d21e284c968700fe3 1 0x006d75f0f710 /data/data/com.geode.launcher/files/geode/unzipped/dankmeme.globed2/dankmeme.globed2.android64.so+0x495710 BuildId: c5eada8116c0f6e8eb8a6a995810433c3dcdb594 2 0x007819bc4b9c /data/app/~~dZyWKnk3vxy emc7LuY4yA==/com.robtopx.geometryjump-6y1HhI10jOa9Pdg7lr TzQ==/split config.arm64 v8a.apk /lib/arm64-v8a/libcocos2dcpp.so+0xac9b9c BuildId: 42f8945feca43dcb3a375f99b8b68cf32456dda8 3 0x00785d3f0374