Android NDK, Address Sanitizer (इसे ASan के नाम से भी जाना जाता है) की शुरुआत में काम करता है को एपीआई लेवल 27 (Android O MR 1) के साथ होना चाहिए.
ASan, नेटिव कोड में मेमोरी की गड़बड़ियों का पता लगाने वाला तेज़ कंपाइलर टूल है. ASan को पता चलता है:
- स्टैक और हीप बफ़र ओवरफ़्लो/अंडरफ़्लो
- मुफ़्त के बाद हीप का इस्तेमाल
- स्टैक का बाहरी दायरा इस्तेमाल करें
- डबल फ़्री/वाइल्ड फ़्री
ASan का सीपीयू ओवरहेड करीब 2x है, ओवरहेड 50% से 2x के बीच है, और मेमोरी ओवरहेड बड़ा होता है (यह आपके ऐलोकेशन पैटर्न पर निर्भर करता है. हालांकि, 2x के क्रम में).
Sample App
ऐप्लिकेशन का नमूना एशिया के लिए बिल्ड वैरिएंट को कॉन्फ़िगर करने का तरीका दिखाता है.
बनाएं
Address Sanitizer की मदद से अपने ऐप्लिकेशन का नेटिव (जेएनआई) कोड बनाने के लिए, यह करें फ़ॉलो किया जा रहा है:
एनडीके-बिल्ड
आपके App.mk में:
APP_STL := c++_shared # Or system, or none.
APP_CFLAGS := -fsanitize=address -fno-omit-frame-pointer
APP_LDFLAGS := -fsanitize=address
आपके Android.mk में हर मॉड्यूल के लिए:
LOCAL_ARM_MODE := arm
सीमेक
अपने मॉड्यूल के Build.gradle में:
android {
defaultConfig {
externalNativeBuild {
cmake {
// Can also use system or none as ANDROID_STL.
arguments "-DANDROID_ARM_MODE=arm", "-DANDROID_STL=c++_shared"
}
}
}
}
आपकी CMakeLists.txt में हर टारगेट के लिए:
target_compile_options(${TARGET} PUBLIC -fsanitize=address -fno-omit-frame-pointer)
set_target_properties(${TARGET} PROPERTIES LINK_FLAGS -fsanitize=address)
चलाएं
Android O MR1 (एपीआई लेवल 27) से शुरू करते हुए, कोई ऐप्लिकेशन रैप शेल स्क्रिप्ट है, जो ऐप्लिकेशन प्रोसेस को रैप कर सकती है या उसकी जगह ले सकती है. इससे आपको अपने ऐप्लिकेशन के स्टार्टअप को कस्टमाइज़ करने के लिए एक डीबग करने लायक ऐप्लिकेशन, जो प्रोडक्शन डिवाइसों पर ASan का इस्तेमाल करके.
- ऐप्लिकेशन मेनिफ़ेस्ट में
android:debuggable
जोड़ें. - सेट करें
useLegacyPackaging
आपके ऐप्लिकेशन कीbuild.gradle
फ़ाइल मेंtrue
तक. रैप शेल स्क्रिप्ट गाइड देखें हमारा वीडियो देखें. - अपने ऐप्लिकेशन मॉड्यूल के
jniLibs
में ASan की रनटाइम लाइब्रेरी जोड़ें. अपनी हर डायरेक्ट्री में, इन कॉन्टेंट वाली
wrap.sh
फ़ाइलें जोड़ेंsrc/main/resources/lib
डायरेक्ट्री.#!/system/bin/sh HERE="$(cd "$(dirname "$0")" && pwd)" export ASAN_OPTIONS=log_to_syslog=false,allow_user_segv_handler=1 ASAN_LIB=$(ls $HERE/libclang_rt.asan-*-android.so) if [ -f "$HERE/libc++_shared.so" ]; then # Workaround for https://github.com/android-ndk/ndk/issues/988. export LD_PRELOAD="$ASAN_LIB $HERE/libc++_shared.so" else export LD_PRELOAD="$ASAN_LIB" fi "$@"
मान लें कि आपके प्रोजेक्ट के ऐप्लिकेशन मॉड्यूल का नाम app
है, तो आपकी फ़ाइनल डायरेक्ट्री
स्ट्रक्चर में नीचे दी गई जानकारी शामिल होनी चाहिए:
<project root>
└── app
└── src
└── main
├── jniLibs
│ ├── arm64-v8a
│ │ └── libclang_rt.asan-aarch64-android.so
│ ├── armeabi-v7a
│ │ └── libclang_rt.asan-arm-android.so
│ ├── x86
│ │ └── libclang_rt.asan-i686-android.so
│ └── x86_64
│ └── libclang_rt.asan-x86_64-android.so
└── resources
└── lib
├── arm64-v8a
│ └── wrap.sh
├── armeabi-v7a
│ └── wrap.sh
├── x86
│ └── wrap.sh
└── x86_64
└── wrap.sh
स्टैक ट्रेस
एड्रेस सैनिटाइज़र को हर malloc
/realloc
/free
पर स्टैक को रिवाइंड करना होगा
कॉल. यहां दो विकल्प दिए गए हैं:
"तेज़" फ़्रेम पॉइंटर पर आधारित अनविंडर नीचे दिए गए दिशा-निर्देशों का पालन करके, बिल्डिंग सेक्शन में दिए गए निर्देशों का पालन करें.
"धीमा" सीएफ़आई ने आराम किया. इस मोड में ASan,
_Unwind_Backtrace
का इस्तेमाल करता है. यह सिर्फ़-funwind-tables
की ज़रूरत होती है, जो आम तौर पर डिफ़ॉल्ट रूप से चालू रहती है.
मॉलिक/realloc/free के लिए फ़ास्ट अनविंडर डिफ़ॉल्ट रूप से सेट है. सबसे धीमी कसरत
स्टैक ट्रेस को डिफ़ॉल्ट तौर पर सेट कर देती है. धीमे आराम करने की सुविधा सभी के लिए चालू की जा सकती है
fast_unwind_on_malloc=0
को ASAN_OPTIONS
वैरिएबल में जोड़कर स्टैक ट्रेस
आपके रैप में.