Fresco: java.lang.UnsatisfiedLinkError ๋กœ๋“œํ•  DSO๋ฅผ ์ฐพ์„ ์ˆ˜ ์—†์Œ: libimagepipeline.so

์— ๋งŒ๋“  2018๋…„ 03์›” 23์ผ  ยท  9์ฝ”๋ฉ˜ํŠธ  ยท  ์ถœ์ฒ˜: facebook/fresco

์ •๋ณด:

  • ํ”„๋ ˆ์Šค์ฝ” ๋ฒ„์ „:1.8.1
  • ํ”Œ๋žซํผ ๋ฒ„์ „: Vivo Android 5.1.1, CPU: arm64-v8a

๋กœ๋“œํ•  DSO๋ฅผ ์ฐพ์„ ์ˆ˜ ์—†์Œ: libimagepipeline.so
com.facebook.soloader.SoLoader.void doLoadLibraryBySoName(java.lang.String,int,android.os.StrictMode$ThreadPolicy)...
03-23 โ€‹โ€‹19:21:55.955 17814 17931 ์ „์ž ์˜ˆ์ˆ : dlopen("/data/data/xxx/lib-main/libimagepipeline.so", RTLD_LAZY) ์‹คํŒจ: dlopen ์‹คํŒจ: "/data/data/xxx/lib-main /libimagepipeline.so"๋Š” 32๋น„ํŠธ๊ฐ€ ์•„๋‹Œ 64๋น„ํŠธ์ž…๋‹ˆ๋‹ค.
03-23 โ€‹โ€‹19:21:55.955 17814 17931 E SoLoader: ๋กœ๋“œํ•  ์ˆ˜ ์—†์Œ: libimagepipeline.so

์„ธ๋ถ€ ์‚ฌํ•ญ

com.facebook.soloader.SoLoader.void doLoadLibraryBySoName(java.lang.String,int,android.os.StrictMode$ThreadPolicy)(SoLoader.java:522)
com.facebook.soloader.SoLoader.void loadLibraryBySoName(java.lang.String,java.lang.String,java.lang.String,int,android.os.StrictMode$ThreadPolicy)(SoLoader.java:420)
com.facebook.soloader.SoLoader.void loadLibrary(java.lang.String,int)(SoLoader.java:370)
com.facebook.soloader.SoLoader.void loadLibrary(java.lang.String)(SoLoader.java:335)
com.facebook.imagepipeline.nativecode.ImagePipelineNativeLoader.void load()(ImagePipelineNativeLoader.java:42)
com.facebook.imagepipeline.memory.NativeMemoryChunk.void()(NativeMemoryChunk.java:33)
com.facebook.imagepipeline.memory.NativeMemoryChunkPool.com.facebook.imagepipeline.memory.NativeMemoryChunk alloc(int)(NativeMemoryChunkPool.java:58)
com.facebook.imagepipeline.memory.NativeMemoryChunkPool.void free(java.lang.Object)(NativeMemoryChunkPool.java:20)

_๋ถ€๋ชจ_##1##_๋ถ€๋ชจ_

_child_## java.lang.Object ํ• ๋‹น(int)##_child_

com.facebook.imagepipeline.memory.BasePool.java.lang.Object get(int)(BasePool.java:257)
com.facebook.imagepipeline.memory.NativePooledByteBufferOutputStream.void(com.facebook.imagepipeline.memory.NativeMemoryChunkPool,int)(NativePooledByteBufferOutputStream.java:51)
com.facebook.imagepipeline.memory.NativePooledByteBufferFactory.com.facebook.imagepipeline.memory.NativePooledByteBuffer newByteBuffer(java.io.InputStream,int)(NativePooledByteBufferFactory.java:98)
com.facebook.imagepipeline.memory.NativePooledByteBufferFactory.com.facebook.common.memory.PooledByteBufferOutputStream newOutputStream(int)(NativePooledByteBufferFactory.java:26)

_๋ถ€๋ชจ_##4##_๋ถ€๋ชจ_

_child_## com.facebook.common.memory.PooledByteBufferOutputStream newOutputStream()##_child_

_child_## com.facebook.common.memory.PooledByteBuffer newByteBuffer(java.io.InputStream,int)##_child_

_child_## com.facebook.common.memory.PooledByteBuffer newByteBuffer(byte[])##_child_

_child_## com.facebook.common.memory.PooledByteBuffer newByteBuffer(java.io.InputStream)##_child_

com.facebook.imagepipeline.producers.LocalFetchProducer.com.facebook.imagepipeline.image.EncodedImage getByteBufferBackedEncodedImage(java.io.InputStream,int)(LocalFetchProducer.java:89)

_๋ถ€๋ชจ_##2##_๋ถ€๋ชจ_

_child_## com.facebook.imagepipeline.image.EncodedImage getEncodedImage(com.facebook.imagepipeline.request.ImageRequest)##_child_

_child_## java.lang.String getProducerName()##_child_

com.facebook.imagepipeline.producers.LocalFetchProducer.com.facebook.imagepipeline.image.EncodedImage getEncodedImage(java.io.InputStream,int)(LocalFetchProducer.java:101)
com.facebook.imagepipeline.producers.LocalFileFetchProducer.com.facebook.imagepipeline.image.EncodedImage getEncodedImage(com.facebook.imagepipeline.request.ImageRequest)(LocalFileFetchProducer.java:34)
com.facebook.imagepipeline.producers.LocalFetchProducer$1.com.facebook.imagepipeline.image.EncodedImage getResult()(LocalFetchProducer.java:54)
com.facebook.imagepipeline.producers.LocalFetchProducer$1.java.lang.Object getResult()(LocalFetchProducer.java:50)
com.facebook.common.executors.StatefulRunnable.void run()(StatefulRunnable.java:45)
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
com.facebook.imagepipeline.core.PriorityThreadFactory$1.void run()(PriorityThreadFactory.java:53)
java.lang.Thread.run(Thread.java:818)

duplicate

๊ฐ€์žฅ ์œ ์šฉํ•œ ๋Œ“๊ธ€

๋ฐ˜์‘ ์—ฟ๋จน์–ด

๋ชจ๋“  9 ๋Œ“๊ธ€

https://github.com/facebook/fresco/issues/2049์˜ ์ค‘๋ณต ๊ฐ€๋Šฅ์„ฑ์ด

์˜ˆ, ์ด๊ฒƒ์€ #2049(ํŠนํžˆ https://github.com/facebook/fresco/issues/2049#issuecomment-367235216)์˜ ๋ณต์ œ๋ณธ์ธ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. @jyh149129 , ํ† ๋ก ์— ์ง‘์ค‘ํ•˜๊ธฐ ์œ„ํ•ด ์—ฌ๊ธฐ์„œ ๋ฌธ์ œ๋ฅผ ์ข…๋ฃŒํ•ฉ๋‹ˆ๋‹ค. :)

@gengjiawen ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค!

๋ฐ˜์‘ ์—ฟ๋จน์–ด

ํ•ด๊ฒฐ์ฑ…์€ ์–ด๋””์— ์žˆ์Šต๋‹ˆ๊นŒ? Fresco ์ข…์†์„ฑ์˜ 1.13.0 ๋ฒ„์ „์—์„œ ๋ฌธ์ œ์— ์ง๋ฉดํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ๋„์™€์ฃผ์„ธ์š”.

/data/data/yourpackage/lib์™€ /data/data/yourpackage/lib-main์˜ cpu_abi๊ฐ€ ๋‹ค๋ฅด๊ธฐ ๋•Œ๋ฌธ์— ์ด ๋ฒ„๊ทธ๊ฐ€ ๋ฐœ์ƒํ•œ ์ด์œ ๋ฅผ ์ฐพ์€ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.
๊ทธ๋ฆฌ๊ณ  ์™œ ๋‹ค๋ฅธ๊ฐ€์š”? ExtractFromZipSoSource.ensureDsos()์— ๊ฒฐํ•จ์ด ์žˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.
์–ด๋–ค ๊ฒฐํ•จ? 32๋น„ํŠธ ๋ฐ 64๋น„ํŠธ so ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ ๋ชจ๋‘ ์žˆ์„ ๋•Œ Android OS๋Š” ์‚ฌ์šฉ์ž๋ฅผ 64๋น„ํŠธ ์•ฑ์œผ๋กœ ์ƒ๊ฐํ•œ๋‹ค๋Š” ๊ฐ€์ •์ด ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ OPPO R7sm(Android 5.1.1 ColorOS: V3.0_170510_beta)์—์„œ ๊ทœ์น™์ด ๊นจ์กŒ์Šต๋‹ˆ๋‹ค.

์ฝ”๋“œ๋ฅผ ์ˆ˜์ •ํ•˜์—ฌ OPPO์˜ ๋ฒ„๊ทธ๋ฅผ ์ˆ˜์ •ํ–ˆ์Šต๋‹ˆ๋‹ค. ๋‚˜์ค‘์— ํ’€ ๋ฆฌํ€˜์ŠคํŠธ๋ฅผ ํ•˜์—ฌ ์—ฌ๋Ÿฌ๋ถ„์˜ ๋„์›€์„ ๊ธฐ๋Œ€ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

๊ต‰์žฅํ•ฉ๋‹ˆ๋‹ค. @artemisia๋ฅผ ์กฐ์‚ฌํ•ด ์ฃผ์…”์„œ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค!

@artemisia ๋‹น์‹ ์˜ PR์„ ๋ณด๊ณ 

์ฃ„์†กํ•ฉ๋‹ˆ๋‹ค, ์ œ ์˜์–ด๊ฐ€ ์ข‹์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

์žฅ์น˜: ๋ชจ๋ฐ”์ผ ์žฅ์น˜: OPPC R7sm(AndroLinkid 5.1.1)
๊ฒฐ๊ณผ:
apk์— armeabi-v7a nad arm64-v8a๊ฐ€ ์žˆ๋Š” ๊ฒฝ์šฐ ์ผ๋ฐ˜์ ์œผ๋กœ arm64-v8a๊ฐ€ ๋กœ๋“œ๋ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ OPPO R7sm์—๋Š” armeabi-v7a๊ฐ€ ๋กœ๋“œ๋ฉ๋‹ˆ๋‹ค.

๊ฒฝ๋กœ ๋ฐ์ดํ„ฐ/์•ฑ/์„ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค./lib/. ์ฐพ๊ธฐ๋Š” arm์ด๊ณ  arm64๊ฐ€ ์•„๋‹™๋‹ˆ๋‹ค. ์ผ๋ฐ˜์ ์œผ๋กœ arm64์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค.

soloader๋ฅผ ์ดˆ๊ธฐํ™”ํ•  ๋•Œ data/app/์˜ ์••์ถ•์„ ํ’‰๋‹ˆ๋‹ค./ .apk. /lib-๋ฉ”์ธ.์ด ํ๋ฆ„์€ ์žฅ์น˜ ์ง€์› abi(ExtractFromZipSoSource.java์˜ ZipUnpacker.ensureDsos())๋ฅผ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.๋ฐ์ดํ„ฐ/์•ฑ/ํ™•์ธ/lib/arm/ .so ๋ฐ */.so apk ํŒŒ์ผ(ApkSoSource.java์˜ ApkUnpacker.shouldExtract()).
ํŒŒ์ผ์ด ๋™์ผํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋ฐ์ดํ„ฐ/๋ฐ์ดํ„ฐ/์— ๋ณต์‚ฌํ•ฉ๋‹ˆ๋‹ค./lib-๋ฉ”์ธ.

์ง€์› ๋ฐ›๊ธฐAbis๋Š” ["arm64-v8a", "armeabi-v7a", "armeabi"]์ž…๋‹ˆ๋‹ค. *.so ํŒŒ์ผ์„ ์ˆœ์ฐจ์ ์œผ๋กœ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.
๊ทธ๋Ÿฌ๋‚˜ data/app//lib/๋Š” OPPC R7sm์˜ arm์ด๋ฏ€๋กœ ํ•ญ์ƒ arm64-v8a os ํŒŒ์ผ์„ data/data/์— ๋ณต์‚ฌํ•˜์‹ญ์‹œ์˜ค./lib-๋ฉ”์ธ.

Lead to *.so๋Š” 32๋น„ํŠธ ๋ฌธ์ œ๊ฐ€ ์•„๋‹Œ 64๋น„ํŠธ ๋ฌธ์ œ์ž…๋‹ˆ๋‹ค.

๋‚ด ์†”๋ฃจ์…˜:

SoLoader ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์ˆ˜์ •ํ•ฉ๋‹ˆ๋‹ค. ์ฒดํฌ ๋ฐ์ดํ„ฐ/์•ฑ/์ถ”๊ฐ€/lib/๋Š” arm ๋˜๋Š” arm64์ž…๋‹ˆ๋‹ค.

ํŒŒ์ผ:
ExtractFromZipSoSource.java

    ...
    final ZipDso[] ensureDsos() {
      if (mDsos == null) {
        Set<String> librariesAbiSet = new LinkedHashSet<>();
        HashMap<String, ZipDso> providedLibraries = new HashMap<>();
        Pattern zipSearchPattern = Pattern.compile(mZipSearchPattern);
        String[] supportedAbis = SysUtil.getSupportedAbis();
        Enumeration<? extends ZipEntry> entries = mZipFile.entries();

+        // Fixed couldn't find DSO to load:  "xxx.os"  is 64-bit instead of 32-bit
+       File sysLibPath =  new File(mContext.getApplicationInfo().nativeLibraryDir);
+       String sysLibAbi = sysLibPath.getPath().substring(sysLibPath.getPath().lastIndexOf("/")+1);
+       if(sysLibAbi.equalsIgnoreCase("arm")) {
+         // sys lib is load armeabi-v7a, this exception case
+         ArrayList<String> newSupportedAbis = new ArrayList();
+         for(String abi : supportedAbis) {
+           if(abi.equalsIgnoreCase("arm64-v8a")) {
+               //skip arm64-v8a
+               continue;
+           }
+
+           newSupportedAbis.add(abi);
+         }
+
+         supportedAbis = newSupportedAbis.toArray(new String[newSupportedAbis.size()]);
+       }


        while (entries.hasMoreElements()) {
          ZipEntry entry = entries.nextElement();
          Matcher m = zipSearchPattern.matcher(entry.getName());
    ...

๋ฐ˜์‘ ์—ฟ๋จน์–ด

Flutter๋ฅผ ํ™˜์˜ํ•ฉ๋‹ˆ๋‹ค

์ด ํŽ˜์ด์ง€๊ฐ€ ๋„์›€์ด ๋˜์—ˆ๋‚˜์š”?
0 / 5 - 0 ๋“ฑ๊ธ‰