Android NDK از HWAddress Sanitizer که با نام HWASan نیز شناخته میشود، با NDK r21 و Android 10 (سطح API 29) پشتیبانی میکند. HWASan فقط در دستگاه های Arm 64 بیتی موجود است.
HWASan یک ابزار تشخیص خطای حافظه مشابه ASan است. در مقایسه با ASan کلاسیک، HWASan دارای:
- سربار CPU مشابه (~2x)
- سربار اندازه کد مشابه (40 تا 50%)
- سربار رم بسیار کوچکتر (10٪ - 35٪)
HWASan همان مجموعه ای از اشکالات ASan را شناسایی می کند:
- سرریز یا زیر جریان بافر پشته و پشته
- استفاده از پشته پس از رایگان
- پشته استفاده خارج از محدوده
- دو برابر رایگان یا وحشی رایگان
علاوه بر این، HWASan همچنین تشخیص می دهد:
- استفاده از پشته پس از بازگشت
نمونه برنامه
یک برنامه نمونه نحوه پیکربندی یک نوع ساخت برای 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
در فایل 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
، این کار نمیکند.
اندروید 14 یا جدیدتر: wrap.sh را اضافه کنید
اگر اندروید 14 یا جدیدتر را اجرا میکنید، میتوانید از اسکریپت wrap.sh برای اجرای برنامه قابل اشکالزدایی خود در هر دستگاه مجهز به Android استفاده کنید. اگر میخواهید مراحل موجود در دستورالعملهای راهاندازی را دنبال کنید، میتوانید این مرحله را نادیده بگیرید.
دستورالعمل های بسته بندی یک اسکریپت wrap.sh را دنبال کنید تا اسکریپت wrap.sh زیر را برای arm64-v8a
اضافه کنید.
#!/system/bin/sh
LD_HWASAN=1 exec "$@"
اجرا کنید
اگر روی یک نسخه اندروید قدیمیتر از ۱۴ اجرا میکنید یا اسکریپت 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 را در اندروید ۱۴ و جدیدتر بسازید و اجرا کنید. می توانید از همان پیکربندی که در Build for ndk-build یا CMake برای فایل های اجرایی خود توضیح داده شده است استفاده کنید. فایل های اجرایی را به دستگاهی که دارای اندروید 14 یا جدیدتر است فشار دهید و آن را به طور معمول با استفاده از پوسته اجرا کنید.
اگر از libc++ استفاده میکنید، مطمئن شوید که از STL مشترک استفاده میکنید و آن را به دستگاه فشار دهید و LD_LIBRARY_PATH
در دایرکتوری حاوی آن هنگام اجرای باینری خود تنظیم کنید.
اگر از Gradle استفاده نمیکنید، به مستندات NDK مراجعه کنید تا نحوه ساخت از خط فرمان با CMake و ndk-build را بیاموزید.
Android 13 یا جدیدتر: راه اندازی
اگر دستگاه شما اندروید 14 یا جدیدتر را اجرا میکند، میتوانید این مرحله را رد کرده و دستورالعملهای استفاده از wrap.sh را در بخش Build دنبال کنید. همچنین میتوانید این بخش را دنبال کنید و از دستورالعملهای استفاده از wrap.sh صرفنظر کنید.
قبل از Android 14، برنامه های HWASan برای اجرا به یک ساخت HWASan از اندروید نیاز دارند. میتوانید تصاویر HWASan از پیش ساخته شده را روی دستگاههای پشتیبانیشده Pixel فلش کنید. بیلدها در ci.android.com در دسترس هستند، جایی که میتوانید بر روی مربع برای بیلد دقیقی که میخواهید پیوند Flash Build را دریافت کنید، کلیک کنید. این مستلزم آن است که نام رمز گوشی خود را بدانید.
شاید راحتتر باشد که مستقیماً به flash.android.com بروید زیرا در آنجا جریان با شناسایی دستگاه شما شروع میشود و فقط ساختهایی را به شما نشان میدهد که میتوانید استفاده کنید. تصاویر زیر جریان راه اندازی در این ابزار را نشان می دهد.
حالت توسعه دهنده را در دستگاه خود فعال کنید و با استفاده از کابل USB آن را به رایانه خود متصل کنید. روی افزودن دستگاه جدید کلیک کنید، دستگاه خود را از کادر گفتگو انتخاب کنید و روی اتصال کلیک کنید.
پس از اتصال دستگاه، روی آن کلیک کنید تا بیلد پیکربندی شود. در کادر Select a build ID ، شاخه aosp-master-with-phones-throttled
انتخاب کنید تا به طور خودکار تصویر صحیح را برای دستگاهی که متصل کرده اید انتخاب کنید.
روی Install کلیک کنید تا دستگاهتان فلش شود.
جزئیات بیشتری در مورد تنظیمات لازم در اسناد Android Flash Tool وجود دارد. همچنین، میتوانید اسناد AOSP را برای دستورالعملهای ساخت تصویر HWASan از منبع بررسی کنید.