Google 致力于为黑人社区推动种族平等。查看具体举措
इस पेज का अनुवाद Cloud Translation API से किया गया है.
Switch to English

पता करने वाला

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

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

  • स्टैक और हीप बफर ओवरफ्लो / अंडरफ्लो
  • मुफ्त के बाद हीप का उपयोग करें
  • बाहर के दायरे का उपयोग करना
  • डबल फ्री / वाइल्ड फ्री

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

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

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

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

यह दस्तावेज़ बताता है कि आसन के साथ एंड्रॉइड के सभी हिस्सों को कैसे बनाया और चलाया जाए। यदि आप ASAN के साथ SDK / NDK ऐप बना रहे हैं, तो इसके बजाय एड्रेस सेनिटाइज़र देखें।

आसन के साथ व्यक्तिगत निष्पादन योग्य बनाना

LOCAL_SANITIZE:=address जोड़ें LOCAL_SANITIZE:=address निष्पादन योग्य के लिए बिल्ड नियम में 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 के उपयुक्त अनुभाग में /init.$device$.rc

setenv LD_LIBRARY_PATH /system/lib/asan

सत्यापित करें कि पठन /proc/$PID/maps द्वारा उपस्थित होने पर प्रक्रिया /system/lib/asan से पुस्तकालयों का उपयोग कर रही है। यदि यह नहीं है, तो आपको 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.

बेहतर स्टैक के निशान

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

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

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

प्रतीकीकरण

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

  • सुनिश्चित करें कि llvm-symbolizer बाइनरी /system/bin में मौजूद है। llvm-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 लक्ष्य को अनदेखा करें (यदि यह उस समय भी है जब आप इसे पढ़ते हैं)।

उपयुक्त system/core/rootdir/init.zygote( 32|64 ).rc 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

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

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

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

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

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

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

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

SANITIZE_TARGET

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

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

make -j42
SANITIZE_TARGET=address make -j42

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

fastboot flash userdata && fastboot flashall

यह साझा पुस्तकालयों के दो सेट बनाता है: सामान्य /system/lib in /system/lib ( /system/lib (पहले मेक इनवोकेशन)), और ASan-instrumented in /data/asan/lib (दूसरा मेक इनवोकेशन)। दूसरी बिल्ड से एक्ज़िक्युटेबल्स पहले बिल्ड से ओवरराइट करते हैं। ASAN- इंस्ट्रूमेंट किए गए एक्जीक्यूटिव्स को एक अलग लाइब्रेरी सर्च पाथ मिलता है जिसमें /system/bin/linker_asan में /system/bin/linker_asan के इस्तेमाल के जरिए /system/bin/linker_asan से पहले /system/lib /data/asan/lib PT_INTERP

जब $SANITIZE_TARGET मूल्य बदल गया है, तो बिल्ड सिस्टम ने मध्यवर्ती ऑब्जेक्ट निर्देशिकाओं को बंद कर दिया। यह सभी लक्ष्यों को फिर से बनाने के लिए बाध्य करता है, जबकि स्थापित बायनेरिज़ को /system/lib तहत संरक्षित करता है।

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

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

SANITIZE_TARGET बिल्ड में इन जैसे एक्ज़ीक्यूटेबल्स को छोड़ दिया जाता है, और पहले मेक इनवोकेशन से वर्जन /system/bin में छोड़ दिया जाता है।

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

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