पता सेनिटाइज़र

AddressSanitizer (ASan) नेटिव कोड में मेमोरी बग्स का पता लगाने के लिए एक तेज़ कंपाइलर-आधारित टूल है।

आसन का पता लगाता है:

  • ढेर और ढेर बफर अतिप्रवाह/अंडरफ्लो
  • मुफ्त के बाद ढेर का उपयोग
  • दायरे के बाहर ढेर का उपयोग
  • डबल फ्री/वाइल्ड फ्री

आसन 32-बिट और 64-बिट एआरएम, प्लस x86 और x86-64 दोनों पर चलता है। ASan का CPU ओवरहेड लगभग 2x है, कोड आकार ओवरहेड 50% और 2x के बीच है, और एक बड़ा मेमोरी ओवरहेड (आपके आवंटन पैटर्न पर निर्भर है, लेकिन 2x के क्रम पर)।

एंड्रॉयड 10 और AArch64 समर्थन पर AOSP मास्टर शाखा हार्डवेयर-त्वरित आसन (HWASan) , कम रैम भूमि के ऊपर के साथ एक समान उपकरण और पता लगाया कीड़े की एक बड़ी रेंज। HWASan, ASan द्वारा खोजे गए बग के अलावा, वापसी के बाद स्टैक के उपयोग का पता लगाता है।

HWASan में समान CPU और कोड आकार का ओवरहेड होता है, लेकिन बहुत छोटा RAM ओवरहेड (15%)। HWASan nondeterministic है। केवल 256 संभावित टैग मान हैं, इसलिए किसी भी बग के गायब होने की 0.4% संभावना है। HWASan के पास अतिप्रवाह का पता लगाने के लिए ASan के सीमित आकार के लाल क्षेत्र नहीं हैं और उपयोग-बाद-मुक्त का पता लगाने के लिए सीमित क्षमता वाले संगरोध हैं, इसलिए HWASan के लिए यह कोई मायने नहीं रखता कि अतिप्रवाह कितना बड़ा है या कितनी देर पहले स्मृति को हटा दिया गया था। यह HWASan को आसन से बेहतर बनाता है। आप के बारे में अधिक पढ़ सकते हैं HWASan के डिजाइन या के उपयोग के बारे एंड्रॉयड पर HWASan

ASan हीप ओवरफ्लो के अलावा स्टैक/ग्लोबल ओवरफ्लो का पता लगाता है, और न्यूनतम मेमोरी ओवरहेड के साथ तेज़ है।

यह दस्तावेज़ वर्णन करता है कि ASan के साथ Android के पुर्ज़े/सभी को कैसे बनाया और चलाया जाए। आप आसन वाले SDK / NDK एप्लिकेशन का निर्माण कर रहे हैं, तो देख पता प्रक्षालक बजाय।

आसन के साथ अलग-अलग एक्जीक्यूटेबल्स को सेनिटाइज करना

जोड़े LOCAL_SANITIZE:=address या sanitize: { address: true } निष्पादन के लिए निर्माण शासन के लिए। आप मौजूदा उदाहरणों के लिए कोड खोज सकते हैं या अन्य उपलब्ध सैनिटाइज़र ढूंढ सकते हैं।

जब एक बग का पता चला है, आसन प्रिंट एक वर्बोज़ मानक आउटपुट में और करने के लिए दोनों की रिपोर्ट logcat और तब प्रक्रिया दुर्घटनाओं।

आसन के साथ साझा पुस्तकालयों को साफ करना

आसन के काम करने के तरीके के कारण, आसन के साथ निर्मित पुस्तकालय का उपयोग केवल एक निष्पादन योग्य द्वारा किया जा सकता है जो कि आसन के साथ बनाया गया है।

एक साझा पुस्तकालय को साफ करने के लिए जो कई निष्पादन योग्य में उपयोग किया जाता है, जिनमें से सभी आसन के साथ नहीं बनाए जाते हैं, आपको पुस्तकालय की दो प्रतियों की आवश्यकता होती है। यह करने के लिए सुझाया गया तरीका करने के लिए निम्नलिखित जोड़ने के लिए है Android.mk प्रश्न में मॉड्यूल के लिए:

LOCAL_SANITIZE:=address
LOCAL_MODULE_RELATIVE_PATH := asan

इस पुट में पुस्तकालय /system/lib/asan के बजाय /system/lib । फिर, अपने निष्पादन योग्य को इसके साथ चलाएं:

LD_LIBRARY_PATH=/system/lib/asan

प्रणाली डेमॉन के लिए, के उपयुक्त अनुभाग के लिए निम्न जोड़ने /init.rc या /init.$device$.rc

setenv LD_LIBRARY_PATH /system/lib/asan

सत्यापित करें कि प्रक्रिया से पुस्तकालयों उपयोग कर रहा है /system/lib/asan जब पढ़ने से वर्तमान /proc/$PID/maps । यदि ऐसा नहीं है, तो आपको SELinux को अक्षम करना पड़ सकता है:

adb root
adb shell setenforce 0
# restart the process with adb shell kill $PID
# if it is a system service, or may be adb shell stop; adb shell start.

बेहतर स्टैक ट्रेस

ASan प्रोग्राम में प्रत्येक मेमोरी आवंटन और डीलोकेशन इवेंट के लिए स्टैक ट्रेस रिकॉर्ड करने के लिए एक तेज़, फ्रेम-पॉइंटर-आधारित अनविंडर का उपयोग करता है। अधिकांश एंड्रॉइड फ्रेम पॉइंटर्स के बिना बनाया गया है। परिणामस्वरूप, आपको अक्सर केवल एक या दो अर्थपूर्ण फ़्रेम मिलते हैं। इसे ठीक करने के लिए, या तो पुस्तकालय को आसन (अनुशंसित!), या इसके साथ पुनर्निर्माण करें:

LOCAL_CFLAGS:=-fno-omit-frame-pointer
LOCAL_ARM_MODE:=arm

या सेट ASAN_OPTIONS=fast_unwind_on_malloc=0 प्रक्रिया वातावरण में। लोड के आधार पर उत्तरार्द्ध बहुत सीपीयू-गहन हो सकता है।

प्रतीकीकरण

प्रारंभ में, ASan रिपोर्ट में बायनेरिज़ और साझा पुस्तकालयों में ऑफ़सेट के संदर्भ होते हैं। स्रोत फ़ाइल और लाइन जानकारी प्राप्त करने के दो तरीके हैं:

  • सुनिश्चित करें कि llvm-symbolizer बाइनरी में मौजूद है /system/binllvm-symbolizer में स्रोतों से बनाया गया है third_party/llvm/tools/llvm-symbolizer
  • के माध्यम से रिपोर्ट फ़िल्टर external/compiler-rt/lib/asan/scripts/symbolize.py स्क्रिप्ट।

दूसरा दृष्टिकोण और अधिक डेटा प्रदान कर सकते हैं (यह है कि, file:line स्थानों पर) क्योंकि मेजबान पर का प्रतीक पुस्तकालयों की उपलब्धता की।

ऐप्स में आसन

आसन जावा कोड में नहीं देख सकता है, लेकिन यह जेएनआई पुस्तकालयों में बग का पता लगा सकता है। के लिए, आप आसन, जो इस मामले में है के साथ निष्पादन का निर्माण करने की जरूरत है /system/bin/app_process( 32|64 ) । यह एक ही समय में डिवाइस पर सभी ऐप्स में आसन को सक्षम बनाता है, जो एक भारी भार है, लेकिन 2 जीबी रैम वाला डिवाइस इसे संभालने में सक्षम होना चाहिए।

जोड़े LOCAL_SANITIZE:=address को app_process में निर्माण नियम frameworks/base/cmds/app_process । ध्यान न दें app_process__asan अब के लिए ही फाइल में लक्ष्य (यदि यह अभी भी समय आप यह पढ़ पर वहाँ है)।

संपादित service zygote उचित की धारा system/core/rootdir/init.zygote( 32|64 ).rc दांतेदार लाइनों युक्त ब्लॉक करने के लिए निम्नलिखित लाइनों को जोड़ने के लिए फ़ाइल class main , यह भी एक ही राशि के द्वारा इंडेंट:

    setenv LD_LIBRARY_PATH /system/lib/asan:/system/lib
    setenv ASAN_OPTIONS allow_user_segv_handler=true

बिल्ड, एडीबी सिंक, फास्टबूट फ्लैश बूट, और रीबूट करें।

रैप संपत्ति का उपयोग करना

पिछले खंड में दृष्टिकोण ASan को सिस्टम के प्रत्येक ऐप में डालता है (वास्तव में, Zygote प्रक्रिया के प्रत्येक वंशज में)। आसन के साथ केवल एक (या कई) ऐप चलाना संभव है, धीमे ऐप स्टार्टअप के लिए कुछ मेमोरी ओवरहेड का व्यापार करना।

इस के साथ अपने एप्लिकेशन शुरू करके किया जा सकता wrap. संपत्ति। निम्नलिखित उदाहरण आसन के तहत जीमेल ऐप चलाता है:

adb root
adb shell setenforce 0  # disable SELinux
adb shell setprop wrap.com.google.android.gm "asanwrapper"

इस संदर्भ में, asanwrapper पुनर्लेखन /system/bin/app_process लिए /system/bin/asan/app_process , जो आसन के साथ बनाया गया है। यह भी कहते हैं /system/lib/asan गतिशील पुस्तकालय खोज पथ के शुरू में। इस तरह से आसन-instrumented पुस्तकालयों /system/lib/asan में सामान्य पुस्तकालयों के लिए पसंद किया जाता है /system/lib जब साथ चल asanwrapper

यदि कोई बग पाया जाता है, तो ऐप क्रैश हो जाता है, और रिपोर्ट लॉग पर प्रिंट हो जाती है।

SANITIZE_TARGET

Android 7.0 और उच्चतर में एक ही बार में ASan के साथ संपूर्ण Android प्लेटफ़ॉर्म बनाने के लिए समर्थन शामिल है। (यदि आप Android 9 से उच्चतर रिलीज़ बना रहे हैं, तो HWASan एक बेहतर विकल्प है।)

एक ही बिल्ड ट्री में निम्न कमांड चलाएँ।

make -j42
SANITIZE_TARGET=address make -j42

इस मोड में, userdata.img अतिरिक्त लाइब्रेरी शामिल हैं और साथ ही डिवाइस के लिए भेजा जाना चाहिए। निम्न कमांड लाइन का प्रयोग करें:

fastboot flash userdata && fastboot flashall

इस साझा पुस्तकालयों के दो सेट बनाता है: सामान्य में /system/lib (पहले मेकअप मंगलाचरण), और में आसन-instrumented /data/asan/lib (दूसरा मेकअप मंगलाचरण)। दूसरे निर्माण से निष्पादन योग्य पहले निर्माण से अधिलेखित कर देते हैं। आसन-instrumented निष्पादनयोग्य एक अलग पुस्तकालय खोज पथ को शामिल मिल /data/asan/lib से पहले /system/lib के उपयोग के माध्यम /system/bin/linker_asan में PT_INTERP

निर्माण प्रणाली clobbers मध्यवर्ती वस्तु निर्देशिका जब $SANITIZE_TARGET मूल्य बदल गया है। जबकि तहत स्थापित बाइनरी संरक्षण यह बलों एक सभी लक्ष्यों के पुनर्निर्माण /system/lib

आसन के साथ कुछ लक्ष्य नहीं बनाए जा सकते:

  • स्थिर रूप से जुड़े निष्पादन योग्य
  • LOCAL_CLANG:=false लक्ष्य
  • LOCAL_SANITIZE:=false के लिए ASan'd नहीं कर रहे हैं SANITIZE_TARGET=address

इस तरह की निष्पादन योग्य में छोड़ दिया जाता है SANITIZE_TARGET निर्माण, और पहले मेकअप मंगलाचरण से संस्करण में छोड़ दिया है /system/bin

इस तरह के पुस्तकालय बिना आसन के बने हैं। वे स्थिर पुस्तकालयों से कुछ आसन कोड शामिल कर सकते हैं जिन पर वे निर्भर हैं।

सहायक दस्तावेज़