Fix debug/release dependencies on libartbase

We load both the debug and release build when running tests.
The different builds have different layout of some classes,
which can currently result in random native heap corruptions.

Fix the build dependencies to avoid the double loading,
and add runtime check to avoid it in the future again.

Test: test.py -b --host --64
Test: test.py -r --target -t 001-HelloWorld
Change-Id: Ie62f91dc06209c91e25ba5f11c9d61243ac7579d
diff --git a/dexlayout/Android.bp b/dexlayout/Android.bp
index 838510b..7313405 100644
--- a/dexlayout/Android.bp
+++ b/dexlayout/Android.bp
@@ -29,29 +29,20 @@
     target: {
         android: {
             shared_libs: [
-                "libartbase",
                 "libartpalette",
-                "libdexfile",
-                "libprofile",
                 "libbase",
             ],
         },
         not_windows: {
             shared_libs: [
-                "libartbase",
                 "libartpalette",
-                "libdexfile",
-                "libprofile",
                 "libbase",
             ],
         },
         windows: {
             cflags: ["-Wno-thread-safety"],
             static_libs: [
-                "libartbase",
                 "libartpalette",
-                "libdexfile",
-                "libprofile",
                 "libbase",
             ],
         },
@@ -78,12 +69,29 @@
             lto: {
                  thin: true,
             },
+            shared_libs: [
+                "libartbase",
+                "libdexfile",
+                "libprofile",
+            ],
+        },
+        not_windows: {
+            shared_libs: [
+                "libartbase",
+                "libdexfile",
+                "libprofile",
+            ],
         },
         windows: {
             enabled: true,
             shared: {
                 enabled: false,
             },
+            static_libs: [
+                "libartbase",
+                "libdexfile",
+                "libprofile",
+            ],
         },
     },
 }
@@ -105,11 +113,29 @@
       "libart-dexlayout-defaults",
       "art_debug_defaults",
     ],
-    shared_libs: [
-        "libdexfiled",
-        "libartbased",
-        "libprofiled",
-    ],
+    target: {
+        android: {
+            shared_libs: [
+                "libartbased",
+                "libdexfiled",
+                "libprofiled",
+            ],
+        },
+        not_windows: {
+            shared_libs: [
+                "libartbased",
+                "libdexfiled",
+                "libprofiled",
+            ],
+        },
+        windows: {
+            static_libs: [
+                "libartbased",
+                "libdexfiled",
+                "libprofiled",
+            ],
+        },
+    },
 }
 
 cc_defaults {
diff --git a/libartbase/Android.bp b/libartbase/Android.bp
index d4fe7b3..339d3c2 100644
--- a/libartbase/Android.bp
+++ b/libartbase/Android.bp
@@ -27,6 +27,7 @@
         "base/enums.cc",
         "base/file_magic.cc",
         "base/file_utils.cc",
+        "base/globals.cc",
         "base/hex_dump.cc",
         "base/hiddenapi_flags.cc",
         "base/logging.cc",
diff --git a/libartbase/base/globals.cc b/libartbase/base/globals.cc
new file mode 100644
index 0000000..e6203a2
--- /dev/null
+++ b/libartbase/base/globals.cc
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <android-base/logging.h>
+
+#if !defined(_WIN32)
+#include <dlfcn.h>
+#endif
+
+#include "globals.h"
+
+namespace art {
+
+#if !defined(_WIN32)
+// Check that we have not loaded both debug and release version of libartbase at the same time.
+static struct CheckLoadedBuild {
+  CheckLoadedBuild() {
+    bool debug_build_loaded = (dlopen("libartbased.so", RTLD_NOW | RTLD_NOLOAD) != nullptr);
+    bool release_build_loaded = (dlopen("libartbase.so", RTLD_NOW | RTLD_NOLOAD) != nullptr);
+    // TODO: The exit calls below are needed as CHECK would cause recursive backtracing. Fix it.
+    if (!debug_build_loaded && !release_build_loaded) {
+      LOG(FATAL_WITHOUT_ABORT) << "Failed to dlopen libartbase.so or libartbased.so";
+      exit(1);
+    }
+    if (kIsDebugBuild && release_build_loaded) {
+      LOG(FATAL_WITHOUT_ABORT) << "Loading libartbased.so while libartbase.so is already loaded";
+      exit(1);
+    }
+    if (!kIsDebugBuild && debug_build_loaded) {
+      LOG(FATAL_WITHOUT_ABORT) << "Loading libartbase.so while libartbased.so is already loaded";
+      exit(1);
+    }
+  }
+} g_check_loaded_build;
+#endif
+
+}  // namespace art
diff --git a/libdexfile/Android.bp b/libdexfile/Android.bp
index 8e131d3..c314d9b 100644
--- a/libdexfile/Android.bp
+++ b/libdexfile/Android.bp
@@ -46,14 +46,12 @@
             ],
             shared_libs: [
                  // For MemMap.
-                 "libartbase",
                  "libartpalette",
                  "liblog",
                  // For common macros.
                  "libbase",
             ],
             export_shared_lib_headers: [
-                "libartbase",
                 "libbase",
             ],
         },
@@ -62,14 +60,12 @@
                 "libziparchive",
                 "libz",
                  // For MemMap.
-                 "libartbase",
                  "libartpalette",
                  "liblog",
                  // For common macros.
                  "libbase",
             ],
             export_shared_lib_headers: [
-                "libartbase",
                 "libbase",
             ],
         },
@@ -78,14 +74,12 @@
                 "libziparchive",
                 "libz",
                  // For MemMap.
-                 "libartbase",
                  "libartpalette",
                  "liblog",
                  // For common macros.
                  "libbase",
             ],
             export_static_lib_headers: [
-                "libartbase",
                 "libbase",
             ],
             cflags: ["-Wno-thread-safety"],
@@ -150,11 +144,33 @@
         keep_symbols: true,
     },
     target: {
+        android: {
+            shared_libs: [
+                 "libartbase",
+            ],
+            export_shared_lib_headers: [
+                "libartbase",
+            ],
+        },
+        not_windows: {
+            shared_libs: [
+                 "libartbase",
+            ],
+            export_shared_lib_headers: [
+                "libartbase",
+            ],
+        },
         windows: {
             enabled: true,
             shared: {
                 enabled: false,
             },
+            static_libs: [
+                 "libartbase",
+            ],
+            export_static_lib_headers: [
+                "libartbase",
+            ],
         },
     },
 }
@@ -166,11 +182,33 @@
         "libdexfile_defaults",
     ],
     target: {
+        android: {
+            shared_libs: [
+                 "libartbased",
+            ],
+            export_shared_lib_headers: [
+                "libartbased",
+            ],
+        },
+        not_windows: {
+            shared_libs: [
+                 "libartbased",
+            ],
+            export_shared_lib_headers: [
+                "libartbased",
+            ],
+        },
         windows: {
             enabled: true,
             shared: {
                 enabled: false,
             },
+            static_libs: [
+                 "libartbased",
+            ],
+            export_static_lib_headers: [
+                "libartbased",
+            ],
         },
     },
 }
@@ -218,8 +256,8 @@
     },
 }
 
-cc_library {
-    name: "libdexfile_external",
+cc_defaults {
+    name: "libdexfile_external-defaults",
     host_supported: true,
     srcs: [
         "external/dex_file_ext.cc",
@@ -227,7 +265,6 @@
     header_libs: ["libdexfile_external_headers"],
     shared_libs: [
         "libbase",
-        "libdexfile",
     ],
 
     stubs: {
@@ -236,6 +273,28 @@
     },
 }
 
+cc_library {
+    name: "libdexfile_external",
+    defaults: [
+        "art_defaults",
+        "libdexfile_external-defaults",
+    ],
+    shared_libs: [
+        "libdexfile",
+    ],
+}
+
+cc_library {
+    name: "libdexfiled_external",
+    defaults: [
+        "art_debug_defaults",
+        "libdexfile_external-defaults",
+    ],
+    shared_libs: [
+        "libdexfiled",
+    ],
+}
+
 art_cc_test {
     name: "art_libdexfile_external_tests",
     host_supported: true,
diff --git a/libdexfile/external/dex_file_supp.cc b/libdexfile/external/dex_file_supp.cc
index ba684fe..446fe16 100644
--- a/libdexfile/external/dex_file_supp.cc
+++ b/libdexfile/external/dex_file_supp.cc
@@ -53,11 +53,15 @@
 #else
   static std::once_flag dlopen_once;
   std::call_once(dlopen_once, []() {
-    constexpr char kLibdexfileExternalLib[] = "libdexfile_external.so";
-    void* handle =
-        dlopen(kLibdexfileExternalLib, RTLD_NOW | RTLD_GLOBAL | RTLD_NODELETE);
-    LOG_ALWAYS_FATAL_IF(handle == nullptr, "Failed to load %s: %s",
-                        kLibdexfileExternalLib, dlerror());
+    // Check which version is already loaded to avoid loading both debug and release builds.
+    // We might also be backtracing from separate process, in which case neither is loaded.
+    const char* so_name = "libdexfiled_external.so";
+    void* handle = dlopen(so_name, RTLD_NOLOAD | RTLD_NOW | RTLD_NODELETE);
+    if (handle == nullptr) {
+      so_name = "libdexfile_external.so";
+      handle = dlopen(so_name, RTLD_NOW | RTLD_GLOBAL | RTLD_NODELETE);
+    }
+    LOG_ALWAYS_FATAL_IF(handle == nullptr, "Failed to load %s: %s", so_name, dlerror());
 
 #define SET_DLFUNC_PTR(CLASS, DLFUNC) \
   do { \
@@ -65,7 +69,7 @@
     LOG_ALWAYS_FATAL_IF(CLASS::g_##DLFUNC == nullptr, \
                         "Failed to find %s in %s: %s", \
                         #DLFUNC, \
-                        kLibdexfileExternalLib, \
+                        so_name, \
                         dlerror()); \
   } while (0)
 
diff --git a/libelffile/Android.bp b/libelffile/Android.bp
index d8db915..092a429 100644
--- a/libelffile/Android.bp
+++ b/libelffile/Android.bp
@@ -26,7 +26,6 @@
         "stream/vector_output_stream.cc",
     ],
     shared_libs: [
-        "libartbase",
         "libbase",
     ],
 }
@@ -37,6 +36,9 @@
         "art_defaults",
         "libelffile-defaults",
     ],
+    shared_libs: [
+        "libartbase",
+    ],
 }
 
 art_cc_library_static {
@@ -45,4 +47,7 @@
         "art_debug_defaults",
         "libelffile-defaults",
     ],
+    shared_libs: [
+        "libartbased",
+    ],
 }
diff --git a/libprofile/Android.bp b/libprofile/Android.bp
index 78bc9d3..19edaef 100644
--- a/libprofile/Android.bp
+++ b/libprofile/Android.bp
@@ -24,9 +24,7 @@
     target: {
         android: {
             shared_libs: [
-                "libartbase",
                 "libartpalette",
-                "libdexfile",
                 "libbase",
             ],
             static_libs: [
@@ -38,9 +36,7 @@
         },
         not_windows: {
             shared_libs: [
-                "libartbase",
                 "libartpalette",
-                "libdexfile",
                 "libziparchive",
                 "libz",
                 "libbase",
@@ -48,11 +44,9 @@
             export_shared_lib_headers: ["libbase"],
         },
         windows: {
-	    cflags: ["-Wno-thread-safety"],
+            cflags: ["-Wno-thread-safety"],
             static_libs: [
-                "libartbase",
                 "libartpalette",
-                "libdexfile",
                 "libziparchive",
                 "libz",
                 "libbase",
@@ -114,13 +108,29 @@
     ],
     export_shared_lib_headers: ["libbase"],
     target: {
+        android: {
+            shared_libs: [
+                "libartbase",
+                "libdexfile",
+            ],
+        },
+        not_windows: {
+            shared_libs: [
+                "libartbase",
+                "libdexfile",
+            ],
+        },
         windows: {
-	    enabled: true,
-	    shared: {
-	        enabled: false,
-	    },
-	},
-    }
+            enabled: true,
+            shared: {
+                enabled: false,
+            },
+            static_libs: [
+                "libartbase",
+                "libdexfile",
+            ],
+        },
+    },
 }
 
 art_cc_library {
@@ -133,6 +143,26 @@
         "libbase",
         "libziparchive",
     ],
+    target: {
+        android: {
+            shared_libs: [
+                "libartbased",
+                "libdexfiled",
+            ],
+        },
+        not_windows: {
+            shared_libs: [
+                "libartbased",
+                "libdexfiled",
+            ],
+        },
+        windows: {
+            static_libs: [
+                "libartbased",
+                "libdexfiled",
+            ],
+        },
+    },
     export_shared_lib_headers: ["libbase"],
 }
 
diff --git a/runtime/Android.bp b/runtime/Android.bp
index 4dc1e5a..cbaa68f 100644
--- a/runtime/Android.bp
+++ b/runtime/Android.bp
@@ -518,6 +518,8 @@
     shared_libs: [
         "libartbase",
         "libdexfile",
+        // We need to eagerly load it so libdexfile_support used from libunwindstack can find it.
+        "libdexfile_external",
         "libprofile",
     ],
     export_shared_lib_headers: [
@@ -546,6 +548,9 @@
     shared_libs: [
         "libartbased",
         "libdexfiled",
+        // We need to eagerly preload it, so that libunwindstack can find it.
+        // Otherwise, it would try to load the non-debug version with dlopen.
+        "libdexfiled_external",
         "libprofiled",
     ],
     export_shared_lib_headers: [
diff --git a/test/Android.bp b/test/Android.bp
index 4513abc..2ed915b 100644
--- a/test/Android.bp
+++ b/test/Android.bp
@@ -538,7 +538,7 @@
 
 art_cc_test_library {
     name: "libnativebridgetest",
-    shared_libs: ["libart"],
+    shared_libs: ["libartd"],
     defaults: [
         "art_test_defaults",
         "art_debug_defaults",
diff --git a/tools/public.libraries.buildbot.txt b/tools/public.libraries.buildbot.txt
index 9b171a2..e23cf2c 100644
--- a/tools/public.libraries.buildbot.txt
+++ b/tools/public.libraries.buildbot.txt
@@ -1,14 +1,6 @@
-libart.so
-libartd.so
-libartbase.so
-libartbased.so
-libdexfile.so
-libdexfiled.so
 libbacktrace.so
 libc.so
 libc++.so
 libdl.so
 libm.so
 libnativehelper.so
-libprofile.so
-libprofiled.so