Yerel kodla uygulamalarda hata ayıklama ve profil oluşturma işlemleri sırasında, işlem başlatılırken etkinleştirilmesi gereken hata ayıklama araçlarının kullanılması genellikle faydalıdır. Bunun için uygulamanızı zigottan klonlamak yerine yeni bir işlemde çalıştırmanız gerekir. Örnekler:
- Sistem çağrılarını strace ile izleme.
- Malloc hata ayıklama veya Address Sanitizer (ASan) ile bellek hatalarını bulma.
- Simpleperf ile profil oluşturma.
Sarmalama kabuğu komut dosyasını kullanma
wrap.sh
ürününü kullanmak kolaydır:
- Aşağıdakileri paketleyen, hata ayıklaması yapılabilecek özel bir APK derleyin:
wrap.sh
adlı bir kabuk komut dosyası. Daha fazla bilgi için Sarmalama kabuğu komut dosyasını oluşturma ve Paket wrap.sh konularını inceleyin.- Kabuk komut dosyanızın ihtiyacı olan ek araçlar (kendi
strace
ikili programınız gibi).
- Hata ayıklaması yapılabilecek APK'yı bir cihaza yükleyin.
- Uygulamayı başlatın.
Sarma kabuğu komut dosyasını oluşturma
wrap.sh
içeren hata ayıklaması yapılabilir bir APK başlattığınızda, sistem komut dosyasını yürütür ve uygulamayı bağımsız değişken olarak başlatma komutunu iletir. Komut dosyası, uygulamayı başlatmaktan sorumludur, ancak herhangi bir ortamda veya bağımsız değişken değişiklikleri yapabilir. Komut dosyası, MirBSD Korn shell (mksh) söz dizimine uygun olmalıdır.
Aşağıdaki snippet'te uygulamayı yeni başlatan basit bir wrap.sh
dosyasının nasıl yazılacağı gösterilmektedir:
#!/system/bin/sh exec "$@"
Malloc hata ayıklaması
wrap.sh
üzerinden malloc hata ayıklama işlevini kullanmak için aşağıdaki satırı eklemeniz gerekir:
#!/system/bin/sh LIBC_DEBUG_MALLOC_OPTIONS=backtrace logwrapper "$@"
ASan
ASan dokümanlarında, ASan için bunun nasıl yapılacağına ilişkin bir örnek bulunmaktadır.
Paket wrap.sh
wrap.sh
ürününden yararlanmak için APK'nızda hata ayıklaması yapılabilir olmalıdır. android:debuggable="true"
ayarının Android manifest dosyanızdaki <application>
öğesinde yapılandırıldığından veya Android Studio kullanıyorsanız build.gradle
dosyasında bir hata ayıklama derlemesi yapılandırdığınızdan emin olun.
Ayrıca, uygulamanızın build.gradle
dosyasında useLegacyPackaging
öğesini true
olarak ayarlamanız gerekir. Çoğu durumda, bu seçenek varsayılan olarak false
değerine ayarlıdır. Bu nedenle sürprizlerden kaçınmak için bunu açıkça true
olarak ayarlamak isteyebilirsiniz.
wrap.sh
komut dosyasını, uygulamanın yerel kitaplıklarıyla paketlemeniz gerekir. Uygulamanız yerel kitaplık içermiyorsa lib dizinini proje dizininize manuel olarak ekleyin. Uygulamanızın desteklediği her mimari için ilgili yerel kitaplık dizini altında sarmalama kabuğu komut dosyasının bir kopyasını sağlamanız gerekir.
Aşağıdaki örnekte, hem ARMv8 hem de x86-64 mimarilerini destekleyecek dosya düzeni gösterilmektedir:
# App Directory |- AndroidManifest.xml |- … |- lib |- arm64-v8a |- ... |- wrap.sh |- x86_64 |- ... |- wrap.sh
Android Studio yalnızca lib/
dizinlerindeki .so
dosyalarını paketler. Bu nedenle, Android Studio kullanıcısıysanız doğru şekilde paketlenmeleri için wrap.sh
dosyalarınızı src/main/resources/lib/*
dizinlerine yerleştirmeniz gerekir.
resources/lib/x86
öğesinin, kullanıcı arayüzünde lib.x86
olarak görüntüleneceğini, ancak aslında bir alt dizin olması gerektiğini unutmayın:
wrap.sh dosyasını kullanırken hata ayıklama
wrap.sh
kullanırken bir hata ayıklayıcı eklemek istiyorsanız kabuk komut dosyanızın hata ayıklamayı manuel olarak etkinleştirmesi gerekir. Bunun nasıl yapılacağı sürüme göre değişir. Bu nedenle bu örnekte, wrap.sh
destekleyen tüm sürümler için uygun seçeneklerin nasıl ekleneceği gösterilmektedir:
#!/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