रैप शेल स्क्रिप्ट

नेटिव कोड से ऐप्लिकेशन को डीबग और प्रोफ़ाइल बनाते समय, अक्सर इनका इस्तेमाल करना मददगार होता है ऐसे डीबगिंग टूल जिन्हें प्रोसेस शुरू होने पर चालू करने की ज़रूरत होती है. इसके लिए ज़रूरी है कि तो आपके ऐप्लिकेशन को ज़ीगोट से क्लोनिंग करने के बजाय एक नई प्रोसेस में चलाया जाता है. उदाहरण के लिए:

रैप शेल स्क्रिप्ट का इस्तेमाल करना

wrap.sh का इस्तेमाल करना आसान है:

  1. डीबग करने लायक ऐसा कस्टम APK कंपाइल करें जो इन चीज़ों को पैकेज करता है:
    • wrap.sh नाम की शेल स्क्रिप्ट. यहां जाएं: रैप शेल स्क्रिप्ट बनाएं और ज़्यादा जानकारी के लिए, पैकेज रैप.श देखें.
    • आपकी शेल स्क्रिप्ट की ज़रूरत के हिसाब से कोई भी अतिरिक्त टूल (जैसे कि आपकी अपनी strace बाइनरी).
  2. डिवाइस पर डीबग करने लायक APK इंस्टॉल करें.
  3. ऐप्लिकेशन लॉन्च करें.

रैप शेल स्क्रिप्ट बनाएं

जब wrap.sh वाला डीबग करने लायक APK लॉन्च किया जाता है, तो सिस्टम और ऐप्लिकेशन को आर्ग्युमेंट के तौर पर शुरू करने के लिए निर्देश देता है. इसकी स्क्रिप्ट का इस्तेमाल, ऐप्लिकेशन को शुरू करने के लिए किया जाता है. हालांकि, वह किसी भी एनवायरमेंट या तर्क के साथ बदलाव. स्क्रिप्ट को उसका पालन करना चाहिए MirBSD Corn Shell (mksh) सिंटैक्स.

नीचे दिया गया स्निपेट एक ऐसी सामान्य wrap.sh फ़ाइल को लिखने का तरीका बताता है जो ऐप्लिकेशन शुरू करता है:

#!/system/bin/sh
exec "$@"

मैलक डीबग

इस्तेमाल करने के लिए मलक डीबग wrap.sh के ज़रिए, आप नीचे दी गई लाइन शामिल करेंगे:

#!/system/bin/sh
LIBC_DEBUG_MALLOC_OPTIONS=backtrace logwrapper "$@"

असैन

उदाहरण के लिए, ASan के साथ ASan के दस्तावेज़.

पैकेज wrap.sh

wrap.sh का फ़ायदा पाने के लिए, आपका APK डीबग करने लायक होना चाहिए. पक्का करें कि android:debuggable="true"सेटिंग को इसमें कॉन्फ़िगर किया गया है: <application> या अगर आप Android Studio का इस्तेमाल कर रहे हैं, तो आपने build.gradle फ़ाइल.

useLegacyPackaging को सेट करना भी ज़रूरी है आपके ऐप्लिकेशन की build.gradle फ़ाइल में true तक. ज़्यादातर मामलों में, यह विकल्प सेट होता है डिफ़ॉल्ट रूप से false पर है, इसलिए आप इसे स्पष्ट रूप से true पर सेट करके किसी भी तरह की परेशानी से बचें.

आपको wrap.sh स्क्रिप्ट को ऐप्लिकेशन की स्थानीय लाइब्रेरी के साथ पैकेज करना होगा. अगर आपने आपके ऐप्लिकेशन में नेटिव लाइब्रेरी नहीं हैं, तो लाइब्रेरी डायरेक्ट्री को मैन्युअल तौर पर आपकी प्रोजेक्ट डायरेक्ट्री में मौजूद है. आपके ऐप्लिकेशन पर इस्तेमाल किए जा सकने वाले हर आर्किटेक्चर के लिए, आपको ये काम करने होंगे उस नेटिव लाइब्रेरी डायरेक्ट्री के तहत रैप शेल स्क्रिप्ट की एक कॉपी उपलब्ध कराएं.

नीचे दिए गए उदाहरण में ARMv8 और x86-64, दोनों पर काम करने वाला फ़ाइल लेआउट दिखाया गया है आर्किटेक्चर:

# App Directory
|- AndroidManifest.xml
|- …
|- lib
   |- arm64-v8a
      |- ...
      |- wrap.sh
   |- x86_64
      |- ...
      |- wrap.sh

Android Studio, lib/ डायरेक्ट्री में मौजूद सिर्फ़ .so फ़ाइलों को पैकेज करता है. इसलिए, अगर आप एक Android Studio उपयोगकर्ता हैं, तो आपको अपनी wrap.sh फ़ाइलें इसके बजाय src/main/resources/lib/* डायरेक्ट्री उपलब्ध कराएं, ताकि उन्हें पैक किया जा सके सही तरीके से.

ध्यान दें कि यूज़र इंटरफ़ेस (यूआई) में resources/lib/x86 इस तरह दिखेगा lib.x86, लेकिन असल में यह एक सबडायरेक्ट्री होनी चाहिए:

Android Studio में पैकेजिंग wrap.sh का उदाहरण

wrap.sh का इस्तेमाल करते समय डीबग करें

अगर आपको wrap.sh का इस्तेमाल करते समय डीबगर अटैच करना है, तो आपकी शेल स्क्रिप्ट मैन्युअल रूप से डीबग करने की सुविधा चालू करनी होगी. अलग-अलग रिलीज़, प्लैटफ़ॉर्म, और नीतियों के हिसाब से इसलिए, इस उदाहरण में उन रिलीज़ के लिए सही विकल्प जोड़ने का तरीका बताया गया है जो सहायता wrap.sh:

#!/system/bin/sh

cmd=$1
shift

os_version=$(getprop ro.build.version.sdk)

if [ "$os_version" -eq "27" ]; then
  cmd="$cmd -Xrunjdwp:transport=dt_android_adb,suspend=n,server=y -Xcompiler-option --debuggable $@"
elif [ "$os_version" -eq "28" ]; then
  cmd="$cmd -XjdwpProvider:adbconnection -XjdwpOptions:suspend=n,server=y -Xcompiler-option --debuggable $@"
else
  cmd="$cmd -XjdwpProvider:adbconnection -XjdwpOptions:suspend=n,server=y $@"
fi

exec $cmd