Fallback to a known good runtime if requested one is not available

Bug: 11463182
Change-Id: I478e7ab9eaee179114b7fa6afe660233e66b0614
diff --git a/JniInvocation.cpp b/JniInvocation.cpp
index e78cff8..acd019a 100644
--- a/JniInvocation.cpp
+++ b/JniInvocation.cpp
@@ -18,6 +18,7 @@
 
 #include <dlfcn.h>
 #include <stdlib.h>
+#include <string.h>
 
 #include <cstddef>
 
@@ -47,12 +48,17 @@
   }
 }
 
+#ifdef HAVE_ANDROID_OS
+static const char* kLibrarySystemProperty = "persist.sys.dalvik.vm.lib";
+#endif
+static const char* kLibraryFallback = "libdvm.so";
+
 bool JniInvocation::Init(const char* library) {
 #ifdef HAVE_ANDROID_OS
   char default_library[PROPERTY_VALUE_MAX];
-  property_get("persist.sys.dalvik.vm.lib", default_library, "libdvm.so");
+  property_get(kLibrarySystemProperty, default_library, kLibraryFallback);
 #else
-  const char* default_library = "libdvm.so";
+  const char* default_library = kLibraryFallback;
 #endif
   if (library == NULL) {
     library = default_library;
@@ -60,8 +66,24 @@
 
   handle_ = dlopen(library, RTLD_NOW);
   if (handle_ == NULL) {
-    ALOGE("Failed to dlopen %s: %s", library, dlerror());
-    return false;
+    if (strcmp(library, kLibraryFallback) == 0) {
+      // Nothing else to try.
+      ALOGE("Failed to dlopen %s: %s", library, dlerror());
+      return false;
+    }
+    // Note that this is enough to get something like the zygote
+    // running, we can't property_set here to fix this for the future
+    // because we are root and not the system user. See
+    // RuntimeInit.commonInit for where we fix up the property to
+    // avoid future fallbacks. http://b/11463182
+    ALOGW("Falling back from %s to %s after dlopen error: %s",
+          library, kLibraryFallback, dlerror());
+    library = kLibraryFallback;
+    handle_ = dlopen(library, RTLD_NOW);
+    if (handle_ == NULL) {
+      ALOGE("Failed to dlopen %s: %s", library, dlerror());
+      return false;
+    }
   }
   if (!FindSymbol(reinterpret_cast<void**>(&JNI_GetDefaultJavaVMInitArgs_),
                   "JNI_GetDefaultJavaVMInitArgs")) {