कला

एंड्रॉइड 8.0 और उच्चतर में, एआरटी टूलिंग इंटरफ़ेस (एआरटी टीआई) कुछ रनटाइम आंतरिक को उजागर करता है, और प्रोफाइलर्स और डिबगर्स को ऐप्स के रनटाइम व्यवहार को प्रभावित करने में सक्षम बनाता है। इसका उपयोग अत्याधुनिक प्रदर्शन उपकरणों को लागू करने के लिए किया जा सकता है जो अन्य प्लेटफार्मों पर देशी एजेंटों को लागू करने के लिए प्रदान किए जाते हैं।

रनटाइम आंतरिक उन एजेंटों के संपर्क में आते हैं जिन्हें रनटाइम प्रक्रिया में लोड किया गया है। ये सीधे कॉल और कॉलबैक के माध्यम से एआरटी के साथ संचार करते हैं। रनटाइम कई एजेंटों का समर्थन करता है ताकि विभिन्न ऑर्थोगोनल-प्रोफाइलिंग चिंताओं को अलग किया जा सके। एजेंटों को या तो रनटाइम प्रारंभ में आपूर्ति की जा सकती है (जब dalvikvm या app_process लागू किया जाता है), या पहले से चल रही प्रक्रिया से जोड़ा जा सकता है।

क्योंकि ऐप और रनटाइम व्यवहार को उपकरणबद्ध करने और संशोधित करने की क्षमता बहुत शक्तिशाली है, दो सुरक्षा उपायों को एआरटी टीआई में एकीकृत किया गया है:

  • सबसे पहले, एजेंट इंटरफ़ेस को उजागर करने वाला कोड, जेवीएमटीआई, रनटाइम प्लगइन के रूप में कार्यान्वित किया जाता है, न कि रनटाइम के मुख्य घटक के रूप में। प्लगइन लोडिंग को प्रतिबंधित किया जा सकता है, ताकि एजेंटों को किसी भी इंटरफ़ेस बिंदु को खोजने से रोका जा सके।
  • दूसरा, ActivityManager क्लास और रनटाइम प्रक्रिया दोनों ही एजेंटों को केवल डिबग करने योग्य ऐप्स से जुड़ने की अनुमति देते हैं। डिबग करने योग्य ऐप्स को उनके डेवलपर्स द्वारा विश्लेषण और उपकरण के लिए साइन-ऑफ कर दिया गया है, और अंतिम उपयोगकर्ताओं को वितरित नहीं किया गया है। Google Play स्टोर डिबग करने योग्य ऐप्स के वितरण की अनुमति नहीं देता है। यह सुनिश्चित करता है कि सामान्य ऐप्स (मुख्य घटकों सहित) को उपकरण या हेरफेर नहीं किया जा सकता है।

डिज़ाइन

एक इंस्ट्रूमेंटेड ऐप में सामान्य प्रवाह और इंटरकनेक्शन चित्र 1 में दिखाया गया है।

Flow and interconnection in an instrumented app
चित्र 1. एक इंस्ट्रुमेंटेड ऐप का प्रवाह और इंटरकनेक्शन

ART प्लगइन libopenjdkjvmti ART TI को उजागर करता है, जिसे प्लेटफ़ॉर्म की आवश्यकताओं और बाधाओं को समायोजित करने के लिए डिज़ाइन किया गया है:

  • क्लास पुनर्परिभाषा Dex फ़ाइलों पर आधारित है, जिसमें क्लास फ़ाइलों के बजाय केवल एक ही क्लास परिभाषा होती है।
  • इंस्ट्रूमेंटेशन और पुनर्परिभाषा के लिए जावा-भाषा एपीआई उजागर नहीं किए गए हैं।

एआरटी टीआई एंड्रॉइड स्टूडियो प्रोफाइलर्स का भी समर्थन करता है।

किसी एजेंट को लोड या संलग्न करें

रनटाइम स्टार्टअप पर एक एजेंट संलग्न करने के लिए, JVMTI प्लगइन और दिए गए एजेंट दोनों को लोड करने के लिए इस कमांड का उपयोग करें:

dalvikvm -Xplugin:libopenjdkjvmti.so -agentpath:/path/to/agent/libagent.so …

जब किसी एजेंट को रनटाइम स्टार्टअप पर लोड किया जाता है तो सुरक्षा उपाय नहीं होते हैं, इसलिए ध्यान रखें कि मैन्युअल रूप से शुरू किया गया रनटाइम सुरक्षा उपायों के बिना पूर्ण संशोधन की अनुमति देता है। (यह एआरटी परीक्षण की अनुमति देता है।)

नोट: यह किसी डिवाइस पर सामान्य ऐप्स (सिस्टम सर्वर सहित) पर लागू नहीं है। ऐप्स को पहले से चल रहे ज़ीगोट से फोर्क किया गया है, और ज़ीगोट प्रक्रिया को एजेंटों को लोड करने की अनुमति नहीं है।

किसी एजेंट को पहले से चल रहे ऐप से जोड़ने के लिए, इस कमांड का उपयोग करें:

adb shell cmd activity attach-agent [process]
/path/to/agent/libagent.so[=agent-options]

यदि JVMTI प्लगइन अभी तक लोड नहीं हुआ है, तो एजेंट संलग्न करने से प्लगइन और एजेंट लाइब्रेरी दोनों लोड हो जाते हैं।

एक एजेंट को केवल एक चालू ऐप से जोड़ा जा सकता है जिसे डिबग करने योग्य के रूप में चिह्नित किया गया है (ऐप के मेनिफेस्ट का हिस्सा, ऐप नोड पर android:debuggable विशेषता को true पर सेट किया गया है)। किसी एजेंट को संलग्न करने की अनुमति देने से पहले ActivityManager क्लास और एआरटी दोनों जांच करते हैं। एक्टिविटीमैनेजर क्लास डिबग करने योग्य स्थिति के लिए वर्तमान ऐप जानकारी ( पैकेजमैनेजर क्लास डेटा से प्राप्त) की जांच करता है, और रनटाइम इसकी वर्तमान स्थिति की जांच करता है, जो ऐप शुरू होने पर सेट किया गया था।

एजेंट स्थान

रनटाइम को एजेंटों को वर्तमान प्रक्रिया में लोड करने की आवश्यकता होती है, ताकि एजेंट सीधे इससे जुड़ सके और इसके साथ संचार कर सके। एआरटी स्वयं उस विशिष्ट स्थान के संबंध में अज्ञेयवादी है जहां से एजेंट आता है। स्ट्रिंग का उपयोग dlopen कॉल के लिए किया जाता है। फ़ाइल सिस्टम अनुमतियाँ और SELinux नीतियाँ वास्तविक लोडिंग को प्रतिबंधित करती हैं।

डिबग करने योग्य ऐप द्वारा चलाए जा सकने वाले एजेंटों को वितरित करने के लिए, निम्न कार्य करें:

  • एजेंट को ऐप के एपीके की लाइब्रेरी निर्देशिका में एम्बेड करें।
  • एजेंट को ऐप की डेटा निर्देशिका में कॉपी करने के लिए run-as उपयोग करें।

शहद की मक्खी

निम्नलिखित विधि android.os.Debug में जोड़ी गई थी।

/**
     * Attach a library as a jvmti agent to the current runtime, with the given classloader
     * determining the library search path.
     * Note: agents may only be attached to debuggable apps. Otherwise, this function will
     * throw a SecurityException.
     *
     * @param library the library containing the agent.
     * @param options the options passed to the agent.
     * @param classLoader the classloader determining the library search path.
     *
     * @throws IOException if the agent could not be attached.
     * @throws a SecurityException if the app is not debuggable.
     */
    public static void attachJvmtiAgent(@NonNull String library, @Nullable String options,
            @Nullable ClassLoader classLoader) throws IOException {

अन्य एंड्रॉइड एपीआई

अटैच-एजेंट कमांड सार्वजनिक रूप से दृश्यमान है। यह कमांड एक JVMTI एजेंट को चल रही प्रक्रिया से जोड़ता है:

adb shell 'am attach-agent com.example.android.displayingbitmaps
\'/data/data/com.example.android.displayingbitmaps/code_cache/libfieldnulls.so=Ljava/lang/Class;.name:Ljava/lang/String;\''

am start -P और am start-profiler/stop-profiler कमांड अटैच-एजेंट कमांड के समान हैं।

जेवीएमटीआई

यह सुविधा JVMTI API को एजेंटों (मूल कोड) के सामने उजागर करती है। महत्वपूर्ण क्षमताओं में शामिल हैं:

  • किसी वर्ग को पुनः परिभाषित करना.
  • ऑब्जेक्ट आवंटन और कचरा संग्रहण पर नज़र रखना।
  • वस्तुओं के संदर्भ वृक्ष का अनुसरण करते हुए, ढेर में सभी वस्तुओं पर पुनरावृत्ति करना।
  • जावा कॉल स्टैक का निरीक्षण करना।
  • सभी थ्रेड्स को निलंबित (और फिर से शुरू) किया जा रहा है।

एंड्रॉइड के विभिन्न संस्करणों पर अलग-अलग क्षमताएं उपलब्ध हो सकती हैं।

अनुकूलता

इस सुविधा के लिए मुख्य रनटाइम समर्थन की आवश्यकता है जो केवल एंड्रॉइड 8.0 और उच्चतर पर उपलब्ध है। डिवाइस निर्माताओं को इस सुविधा को लागू करने के लिए कोई बदलाव करने की आवश्यकता नहीं है। यह AOSP का हिस्सा है.

मान्यकरण

सीटीएस एंड्रॉइड 8 और उच्चतर पर निम्नलिखित का परीक्षण करता है:

  • परीक्षण जो एजेंट डिबग करने योग्य ऐप्स से जोड़ते हैं, और गैर-डिबग करने योग्य ऐप्स से संलग्न करने में विफल रहते हैं।
  • सभी कार्यान्वित JVMTI API का परीक्षण करें
  • परीक्षण करता है कि एजेंटों के लिए बाइनरी इंटरफ़ेस स्थिर है

एंड्रॉइड 9 और उच्चतर में अतिरिक्त परीक्षण जोड़े गए हैं, और उन रिलीज़ों के लिए सीटीएस परीक्षणों में शामिल किए गए हैं।