Ошибка dlopen для привилегированного приложения при обновлении инструментов сборки Gradle с 3.6.1 до 4.1.0

У меня есть приложение, которое находится в /system/priv-app/MyTestApp. Средой исходного кода Android является Android P (API 28).

Сначала MyTestApp.apk был собран с помощью инструментов сборки gradle 3.6.1. Затем я обновляю его до 4.1.0 и создаю новый MyTestApp.apk, предварительно собрав его в ПЗУ. Итак, происходит сбой.

E AndroidRuntime: java.lang.UnsatisfiedLinkError: dlopen failed: library "/system/priv-app/MyTestApp/MyTestApp.apk!/lib/armeabi-v7a/libmytest.so" not found
E AndroidRuntime:       at java.lang.Runtime.loadLibrary0(Runtime.java:1016)
E AndroidRuntime:       at java.lang.System.loadLibrary(System.java:1669)

Я вытаскиваю файл /system/priv-app/MyTestApp/MyTestApp.apk, извлекаю файл и обнаруживаю, что libmytest.so существует. Это определенно вызвано обновлением инструментов сборки Gradle. Но не могу найти причину. Может ли кто-нибудь помочь?


person Tinker Sun    schedule 06.01.2021    source источник


Ответы (4)


Изучив исходный код, я обнаружил, что в bionic/linker/linker.cpp

if (entry.method != kCompressStored || (entry.offset % PAGE_SIZE) != 0) {
  close(fd);
  return -1;
}

entry.offset % PAGE_SIZE != 0 это условие не выполняется.

Так что я предполагаю, что что-то не так с zipalign AGP 4.1+.

Все еще изучаю это.

person Tinker Sun    schedule 08.01.2021

Система сборки Android будет распаковывать файлы dex, встроенные в apk, для привилегированных приложений, если свойство DONT_UNCOMPRESS_PRIV_APPS_DEXS не определено. Определение распаковки приведено ниже.

# Uncompress dex files embedded in an apk.
#
define uncompress-dexs
$(hide) if (zipinfo $@ '*.dex' 2>/dev/null | grep -v ' stor ' >/dev/null) ; then \
  [email protected]; \
  rm -rf $$tmpdir && mkdir $$tmpdir; \
  unzip -q $@ '*.dex' -d $$tmpdir && \
  zip -qd $@ '*.dex' && \
  ( cd $$tmpdir && find . -type f | sort | zip -qD -X -0 ../$(notdir $@) -@ ) && \
  rm -rf $$tmpdir; \
  fi
endef

Когда apk создается с помощью AGP 4.0, после распаковки-dexs его можно успешно проверить с помощью инструмента zipalign.

zipalign -v -c -p 4 MyTestApp.apk

Но при сборке с AGP 4.1+ (включая 7.0-альфа) ее нельзя проверить с помощью инструмента zipalign.

Но пока не нашел причину. Просто догадайтесь, что есть что-то новое в архиве apk в AGP 4.1+.

person Tinker Sun    schedule 11.01.2021

android.useNewApkCreator=false

Добавьте эту строку в gradle.properties, чтобы решить эту проблему.

Но начиная с AGP 3.6+ значение этого свойства по умолчанию равно true. Так что не должно быть разницы между AGP 4.0 и AGP 4.1.

Я весьма озадачен. Возможно, есть еще какие-то условия для вступления в силу.

person Tinker Sun    schedule 11.01.2021
comment
zipflinger не был включен для выпускных сборок до AGP 4.1. Таким образом, это подтверждает, что это вызвано zipflinger. - person Tinker Sun; 11.01.2021
comment
см. issuetracker.google.com/issues/163841076#comment2. - person Tinker Sun; 11.01.2021

обратитесь к самому последнему коду, метод uncompress-dexs подобен ниже

https://android.googlesource.com/platform/build/+/master/core/definitions.mk#2385

# Uncompress dex files embedded in an apk.
#
define uncompress-dexs
  if (zipinfo $@ '*.dex' 2>/dev/null | grep -v ' stor ' >/dev/null) ; then \
    $(ZIP2ZIP) -i $@ -o [email protected] -0 "classes*.dex" && \
    mv -f [email protected] $@ ; \
  fi
endef
person Tinker Sun    schedule 12.01.2021