diff --git a/java/com/facebook/soloader/MinElf.java b/java/com/facebook/soloader/MinElf.java index 423e7a9..560428c 100644 --- a/java/com/facebook/soloader/MinElf.java +++ b/java/com/facebook/soloader/MinElf.java @@ -16,11 +16,13 @@ package com.facebook.soloader; +import android.util.Log; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.nio.ByteBuffer; import java.nio.ByteOrder; +import java.nio.channels.ClosedByInterruptException; import java.nio.channels.FileChannel; /** @@ -32,6 +34,8 @@ */ public final class MinElf { + private static final String TAG = "MinElf"; + public static enum ISA { NOT_SO("not_so"), X86("x86"), @@ -65,10 +69,18 @@ public String toString() { public static String[] extract_DT_NEEDED(File elfFile) throws IOException { FileInputStream is = new FileInputStream(elfFile); - try { - return extract_DT_NEEDED(is.getChannel()); - } finally { - is.close(); // Won't throw + while (true) { + try { + return extract_DT_NEEDED(is.getChannel()); + } catch (ClosedByInterruptException e) { + // Some other thread interrupted us. We need to try again. This is + // especially important since this is often used within the context of + // a static initializer. A failure here will get memoized resulting in + // all future attempts to load the same class to fail. + Log.e(TAG, "retrying extract_DT_NEEDED due to ClosedByInterruptException", e); + } finally { + is.close(); // Won't throw + } } }