Android NDK, HWAddress Sanitizer के साथ काम करता है. इसे HWASan भी कहा जाता है. यह सुविधा NDK r21 और Android 10 (एपीआई लेवल 29) से उपलब्ध है. HWASan की सुविधा, सिर्फ़ 64-बिट Arm डिवाइसों पर उपलब्ध है.
HWASan, ASan की तरह ही मेमोरी में होने वाली गड़बड़ियों का पता लगाने वाला टूल है. क्लासिक ASan की तुलना में, HWASan में ये सुविधाएं हैं:
- सीपीयू का ओवरहेड, ASan के बराबर है (करीब 2x)
- कोड साइज़ का ओवरहेड, ASan के बराबर है (40 – 50%)
- रैम का ओवरहेड, ASan की तुलना में बहुत कम है (10% – 35%)
HWASan, ASan की तरह ही इन गड़बड़ियों का पता लगाता है:
- स्टैक और हीप बफ़र ओवरफ़्लो या अंडरफ़्लो
- फ़्री की गई मेमोरी को इस्तेमाल करने की गड़बड़ी
- स्कोप से बाहर स्टैक का इस्तेमाल
- डबल फ़्री या वाइल्ड फ़्री
इसके अलावा, HWASan इन गड़बड़ियों का भी पता लगाता है:
- वापस आने के बाद स्टैक का इस्तेमाल
Sample App
सैंपल ऐप्लिकेशन से पता चलता है कि hwasan के लिए, बिल्ड वैरिएंट को कैसे कॉन्फ़िगर किया जाता है.
बनाएं
HWAddress Sanitizer की मदद से, अपने ऐप्लिकेशन का नेटिव (JNI) कोड बनाने के लिए, यह तरीका अपनाएं:
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 14 या इसके बाद के वर्शन का इस्तेमाल किया जा रहा है, तो किसी भी Android डिवाइस पर डीबग किए जा सकने वाले ऐप्लिकेशन को चलाने के लिए, a wrap.sh स्क्रिप्ट का इस्तेमाल किया जा सकता है. अगर आपने सेटअप के निर्देशों में दिए गए चरणों का पालन किया है , तो इस चरण को छोड़ा जा सकता है.
arm64-v8a के लिए, यहां दी गई wrap.sh स्क्रिप्ट जोड़ने के लिए,
wrap.sh स्क्रिप्ट को पैकेज करने के निर्देश देखें.
#!/system/bin/sh
LD_HWASAN=1 exec "$@"
चलाएं
अगर Android 14 से पहले के किसी वर्शन का इस्तेमाल किया जा रहा है या wrap.sh स्क्रिप्ट नहीं जोड़ी गई है, तो ऐप्लिकेशन चलाने से पहले, सेटअप के निर्देश देखें.
ऐप्लिकेशन को सामान्य तरीके से चलाएं. मेमोरी में गड़बड़ी का पता चलने पर, ऐप्लिकेशन SIGABRT के साथ क्रैश हो जाता है और लॉगकैट में पूरी जानकारी वाला मैसेज दिखता है. मैसेज की एक कॉपी, /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)
मैसेज के बाद, डीबग करने से जुड़ी अतिरिक्त जानकारी भी दिख सकती है. इसमें ऐप्लिकेशन में मौजूद लाइव थ्रेड की सूची, आस-पास की मेमोरी के लिए टैग, और सीपीयू रजिस्टर की वैल्यू शामिल होती हैं.
HWASan से जुड़ी गड़बड़ियों के मैसेज के बारे में ज़्यादा जानकारी पाने के लिए, HWASan की रिपोर्ट को समझना लेख पढ़ें.
कमांड-लाइन एक्ज़ीक्यूटेबल बनाना
Android 14 और इसके बाद के वर्शन पर, HWASan की मदद से इंस्ट्रूमेंट किए गए एक्ज़ीक्यूटेबल बनाए और चलाए जा सकते हैं. 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 ऐप्लिकेशन चलाने के लिए, Android के HWASan बिल्ड की ज़रूरत होती है. HWASan की पहले से बनी इमेज को, Pixel के उन डिवाइसों पर फ़्लैश किया जा सकता है जो इस सुविधा के साथ काम करते हैं. बिल्ड, ci.android.com पर उपलब्ध हैं. यहां, आपको जिस बिल्ड को डाउनलोड करना है उसके स्क्वेयर पर क्लिक करके, फ़्लैश बिल्ड का लिंक पाया जा सकता है. इसके लिए, आपको अपने फ़ोन का कोडनेम पता होना चाहिए.
इसके बजाय, सीधे flash.android.com पर जाना ज़्यादा आसान हो सकता है, क्योंकि यहां डिवाइस का पता लगाने के बाद ही, आपको वे बिल्ड दिखते हैं जिनका इस्तेमाल किया जा सकता है. यहां दी गई इमेज में, इस टूल में सेटअप का तरीका दिखाया गया है.
अपने डिवाइस पर डेवलपर मोड चालू करें और यूएसबी केबल का इस्तेमाल करके, इसे अपने कंप्यूटर से कनेक्ट करें. नया डिवाइस जोड़ें पर क्लिक करें. इसके बाद, डायलॉग में से अपना डिवाइस चुनें और कनेक्ट करें पर क्लिक करें.
डिवाइस कनेक्ट होने के बाद, बिल्ड को कॉन्फ़िगर करने के लिए उस पर क्लिक करें.
बिल्ड आईडी चुनें बॉक्स में, aosp-master-with-phones-throttled ब्रांच चुनें, ताकि कनेक्ट किए गए डिवाइस के लिए सही इमेज अपने-आप चुनी जा सके.
अपने डिवाइस को फ़्लैश करने के लिए, इंस्टॉल करें पर क्लिक करें.
Android Flash Tool के दस्तावेज़ में, ज़रूरी सेटअप के बारे में ज़्यादा जानकारी दी गई है. इसके अलावा, सोर्स से HWASan इमेज बनाने के निर्देशों के लिए, AOSP का दस्तावेज़ देखा जा सकता है.