HWAddress Sanitizer

«جعبه‌ابزار توسعه بومی Android» از HWAddress Sanitizer که با نام HWASan نیز شناخته می‌شود، از NDK r21 و Android 10 (سطح API 29) پشتیبانی می‌کند. ‫HWASan فقط در دستگاه‌های Arm‏ ۶۴ بیتی دردسترس است.

‫HWASan ابزاری برای تشخیص خطای حافظه است که مشابه ASan است. درمقایسه با ASan کلاسیک، HWASan:

  • سربار CPU مشابه (تقریباً ۲ برابر)
  • سربار اندازه کد مشابه (۴۰ تا ۵۰ درصد)
  • سربار RAM بسیار کمتر (۱۰٪ تا ۳۵٪)

HWASan همان مجموعه اشکالاتی را که ASan شناسایی می‌کند، شناسایی می‌کند:

  • سرریز یا سرریز منفی پشته و انباشته بافر
  • استفاده از پشته پس‌از رایگان
  • استفاده از پشته خارج از محدوده
  • دونفره آزاد یا دونفره وحشی

علاوه‌براین، HWASan موارد زیر را نیز شناسایی می‌کند:

  • استفاده از پشته پس‌از برگشت

Sample App

یک برنامه نمونه نشان می‌دهد که چگونه یک متغیر ساخت را برای hwasan پیکربندی کنید.

ساخت

برای ساختن کد بومی (JNI) برنامه‌تان با HWAddress Sanitizer، کارهای زیر را انجام دهید:

ndk-build

در فایل Application.mk:

APP_STL := c++_shared # Or system, or none, but not c++_static.
APP_CFLAGS := -fsanitize=hwaddress -fno-omit-frame-pointer
APP_LDFLAGS := -fsanitize=hwaddress

CMake (Gradle Groovy)‎

در فایل build.gradle واحدتان:

android {
    defaultConfig {
        externalNativeBuild {
            cmake {
                # Can also use system or none as ANDROID_STL, but not c++_static.
                arguments "-DANDROID_STL=c++_shared"
            }
        }
    }
}

برای هر هدف در CMakeLists.txt:

target_compile_options(${TARGET} PUBLIC -fsanitize=hwaddress -fno-omit-frame-pointer)
target_link_options(${TARGET} PUBLIC -fsanitize=hwaddress)

با NDK 27 یا جدیدتر، می‌توانید از موارد زیر نیز در build.gradle خود استفاده کنید و نیازی به تغییر CMakeLists.txt ندارید:

android {
    defaultConfig {
        externalNativeBuild {
            cmake {
                arguments "-DANDROID_SANITIZE=hwaddress"
            }
        }
    }
}

این ویژگی هنگام استفاده از ANDROID_USE_LEGACY_TOOLCHAIN_FILE=false کار نخواهد کرد.

CMake (Gradle Kotlin)

در فایل build.gradle واحدتان:

android {
    defaultConfig {
        externalNativeBuild {
            cmake {
                # Can also use system or none as ANDROID_STL, but not c++_static.
                arguments += "-DANDROID_STL=c++_shared"
            }
        }
    }
}

برای هر هدف در CMakeLists.txt:

target_compile_options(${TARGET} PUBLIC -fsanitize=hwaddress -fno-omit-frame-pointer)
target_link_options(${TARGET} PUBLIC -fsanitize=hwaddress)

با NDK 27 یا جدیدتر، می‌توانید از موارد زیر نیز در build.gradle خود استفاده کنید و نیازی به تغییر CMakeLists.txt ندارید:

android {
    defaultConfig {
        externalNativeBuild {
            cmake {
                arguments += "-DANDROID_SANITIZE=hwaddress"
            }
        }
    }
}

این ویژگی هنگام استفاده از ANDROID_USE_LEGACY_TOOLCHAIN_FILE=false کار نخواهد کرد.

Android 14 یا جدیدتر: wrap.sh را اضافه کنید

اگر از Android نسخه ۱۴ یا جدیدتر استفاده می‌کنید، می‌توانید از اسکریپت wrap.sh برای اجرای برنامه قابل‌اشکال‌زدایی خود در هر دستگاه مجهز به Android استفاده کنید. اگر انتخاب کرده‌اید که مراحل در دستورالعمل‌های راه‌اندازی را دنبال کنید، می‌توانید از این مرحله رد شوید.

دستورالعمل‌های مربوط به بسته‌بندی کردن اسکریپت wrap.sh را دنبال کنید تا اسکریپت wrap.sh زیر را برای arm64-v8a اضافه کنید.

#!/system/bin/sh
LD_HWASAN=1 exec "$@"

اجرا

اگر از نسخه Android قدیمی‌تر از ۱۴ استفاده می‌کنید یا wrap.sh را اضافه نکرده‌اید، پیش‌از اجرای برنامه، دستورالعمل‌های راه‌اندازی را دنبال کنید.

برنامه را طبق معمول اجرا کنید. وقتی خطای حافظه تشخیص داده می‌شود، برنامه با SIGABRT خراب می‌شود و پیام مفصلی در logcat چاپ می‌کند. نسخه‌ای از پیام را می‌توانید در فایلی در /data/tombstones پیدا کنید که به این شکل است:

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)

ممکن است این پیام با اطلاعات اشکال‌زدایی اضافی، ازجمله فهرست رشته‌های فعال در برنامه، برچسب‌های تخصیص‌های حافظه نزدیک، و مقادیر ثبت‌کننده CPU همراه باشد.

برای اطلاعات بیشتر درباره پیام‌های خطای HWASan، به آشنایی با گزارش‌های HWASan مراجعه کنید.

ساختن فایل‌های اجرایی خط فرمان

می‌توانید فایل‌های اجرایی ابزاربندی‌شده با HWASan را در Android 14 و نسخه‌های جدیدتر بسازید و اجرا کنید. می‌توانید از همان پیکربندی شرح‌داده‌شده در ساخت برای ndk-build یا CMake برای فایل‌های اجرایی‌تان استفاده کنید. فایل‌های اجرایی را به دستگاهی که Android 14 یا جدیدتر دارد ارسال کنید و آن را به‌طور معمول بااستفاده از پوسته اجرا کنید.

اگر از libc++ استفاده می‌کنید، مطمئن شوید که از STL مشترک استفاده می‌کنید و آن را به دستگاه انتقال دهید و LD_LIBRARY_PATH را روی دایرکتوری حاوی آن هنگام اجرای باینری تنظیم کنید.

اگر از Gradle استفاده نمی‌کنید، برای آشنایی با نحوه ساختن از خط فرمان با CMake و ndk-build، به اسناد NDK مراجعه کنید.

‫Android 13 یا نسخه‌های قدیمی‌تر: راه‌اندازی

اگر دستگاهتان Android 14 یا جدیدتر دارد، می‌توانید از این مرحله رد شوید و دستورالعمل‌های استفاده از wrap.sh را در بخش ساخت دنبال کنید. همچنین می‌توانید این بخش را دنبال کنید و دستورالعمل‌های استفاده از wrap.sh را نادیده بگیرید.

قبل‌از Android 14، برنامه‌های HWASan برای اجرا به ساخت HWASan از Android نیاز دارند. می‌توانید تصاویر ازپیش ساخته‌شده HWASan را در دستگاه‌های Pixel پشتیبانی‌شده فلاش کنید. ساخت‌ها در ci.android.com دردسترس هستند، جایی که می‌توانید روی مربع ساخت دقیق موردنظرتان کلیک کنید تا پیوند ساخت Flash را دریافت کنید. برای این کار باید نام کد تلفنتان را بدانید.

فلش کردن ساخت دستگاه

شاید آسان‌تر باشد که مستقیماً به flash.android.com بروید زیرا در آنجا جریان با شناسایی دستگاهتان شروع می‌شود و فقط ساخت‌هایی را به شما نشان می‌دهد که می‌توانید استفاده کنید. تصاویر زیر جریان راه‌اندازی در این ابزار را نشان می‌دهد.

حالت توسعه‌دهنده را در دستگاهتان فعال کنید و آن را بااستفاده از کابل USB به رایانه وصل کنید. روی افزودن دستگاه جدید کلیک کنید، دستگاهتان را از چارگوش انتخاب کنید، و روی اتصال کلیک کنید.

شناسایی کردن دستگاه برای فلش کردن دستگاه موردنظر را برای اتصال انتخاب کنید

پس‌از متصل شدن دستگاه، روی آن کلیک کنید تا ساخت را پیکربندی کنید. در چارگوش انتخاب شناسه ساخت، aosp-master-with-phones-throttledشاخه را انتخاب کنید تا تصویر صحیح برای دستگاه متصل‌شده به‌طور خودکار انتخاب شود.

دستگاه موردنظر را برای فلش کردن انتخاب کنید تأیید گزینه‌های فلش کردن و فلش کردن دستگاه

برای فلش کردن دستگاه، روی نصب کلیک کنید.

جزئیات بیشتر درباره راه‌اندازی لازم در سند Android Flash Tool وجود دارد. یا می‌توانید اسناد AOSP را برای دستورالعمل‌های ساختن تصویر HWASan از منبع بررسی کنید.