Home | History | Annotate | Download | only in runtime
      1 /*
      2  * Copyright (C) 2012 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #include "common_runtime_test.h"
     18 
     19 #include <cstdio>
     20 #include <dirent.h>
     21 #include <dlfcn.h>
     22 #include <fcntl.h>
     23 #include "nativehelper/ScopedLocalRef.h"
     24 #include <stdlib.h>
     25 
     26 #include "../../external/icu/icu4c/source/common/unicode/uvernum.h"
     27 #include "android-base/stringprintf.h"
     28 
     29 #include "art_field-inl.h"
     30 #include "base/logging.h"
     31 #include "base/macros.h"
     32 #include "base/stl_util.h"
     33 #include "base/unix_file/fd_file.h"
     34 #include "class_linker.h"
     35 #include "compiler_callbacks.h"
     36 #include "dex_file-inl.h"
     37 #include "gc/heap.h"
     38 #include "gc_root-inl.h"
     39 #include "gtest/gtest.h"
     40 #include "handle_scope-inl.h"
     41 #include "interpreter/unstarted_runtime.h"
     42 #include "java_vm_ext.h"
     43 #include "jni_internal.h"
     44 #include "mem_map.h"
     45 #include "mirror/class-inl.h"
     46 #include "mirror/class_loader.h"
     47 #include "native/dalvik_system_DexFile.h"
     48 #include "noop_compiler_callbacks.h"
     49 #include "os.h"
     50 #include "primitive.h"
     51 #include "runtime-inl.h"
     52 #include "scoped_thread_state_change-inl.h"
     53 #include "thread.h"
     54 #include "well_known_classes.h"
     55 
     56 int main(int argc, char **argv) {
     57   // Gtests can be very noisy. For example, an executable with multiple tests will trigger native
     58   // bridge warnings. The following line reduces the minimum log severity to ERROR and suppresses
     59   // everything else. In case you want to see all messages, comment out the line.
     60   setenv("ANDROID_LOG_TAGS", "*:e", 1);
     61 
     62   art::InitLogging(argv, art::Runtime::Abort);
     63   LOG(INFO) << "Running main() from common_runtime_test.cc...";
     64   testing::InitGoogleTest(&argc, argv);
     65   return RUN_ALL_TESTS();
     66 }
     67 
     68 namespace art {
     69 
     70 using android::base::StringPrintf;
     71 
     72 static const uint8_t kBase64Map[256] = {
     73   255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
     74   255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
     75   255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
     76   255, 255, 255, 255, 255, 255, 255,  62, 255, 255, 255,  63,
     77   52,  53,  54,  55,  56,  57,  58,  59,  60,  61, 255, 255,
     78   255, 254, 255, 255, 255,   0,   1,   2,   3,   4,   5,   6,
     79     7,   8,   9,  10,  11,  12,  13,  14,  15,  16,  17,  18,  // NOLINT
     80    19,  20,  21,  22,  23,  24,  25, 255, 255, 255, 255, 255,  // NOLINT
     81   255,  26,  27,  28,  29,  30,  31,  32,  33,  34,  35,  36,
     82    37,  38,  39,  40,  41,  42,  43,  44,  45,  46,  47,  48,  // NOLINT
     83    49,  50,  51, 255, 255, 255, 255, 255, 255, 255, 255, 255,  // NOLINT
     84   255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
     85   255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
     86   255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
     87   255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
     88   255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
     89   255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
     90   255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
     91   255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
     92   255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
     93   255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
     94   255, 255, 255, 255
     95 };
     96 
     97 uint8_t* DecodeBase64(const char* src, size_t* dst_size) {
     98   CHECK(dst_size != nullptr);
     99   std::vector<uint8_t> tmp;
    100   uint32_t t = 0, y = 0;
    101   int g = 3;
    102   for (size_t i = 0; src[i] != '\0'; ++i) {
    103     uint8_t c = kBase64Map[src[i] & 0xFF];
    104     if (c == 255) continue;
    105     // the final = symbols are read and used to trim the remaining bytes
    106     if (c == 254) {
    107       c = 0;
    108       // prevent g < 0 which would potentially allow an overflow later
    109       if (--g < 0) {
    110         *dst_size = 0;
    111         return nullptr;
    112       }
    113     } else if (g != 3) {
    114       // we only allow = to be at the end
    115       *dst_size = 0;
    116       return nullptr;
    117     }
    118     t = (t << 6) | c;
    119     if (++y == 4) {
    120       tmp.push_back((t >> 16) & 255);
    121       if (g > 1) {
    122         tmp.push_back((t >> 8) & 255);
    123       }
    124       if (g > 2) {
    125         tmp.push_back(t & 255);
    126       }
    127       y = t = 0;
    128     }
    129   }
    130   if (y != 0) {
    131     *dst_size = 0;
    132     return nullptr;
    133   }
    134   std::unique_ptr<uint8_t[]> dst(new uint8_t[tmp.size()]);
    135   *dst_size = tmp.size();
    136   std::copy(tmp.begin(), tmp.end(), dst.get());
    137   return dst.release();
    138 }
    139 
    140 ScratchFile::ScratchFile() {
    141   // ANDROID_DATA needs to be set
    142   CHECK_NE(static_cast<char*>(nullptr), getenv("ANDROID_DATA")) <<
    143       "Are you subclassing RuntimeTest?";
    144   filename_ = getenv("ANDROID_DATA");
    145   filename_ += "/TmpFile-XXXXXX";
    146   int fd = mkstemp(&filename_[0]);
    147   CHECK_NE(-1, fd) << strerror(errno) << " for " << filename_;
    148   file_.reset(new File(fd, GetFilename(), true));
    149 }
    150 
    151 ScratchFile::ScratchFile(const ScratchFile& other, const char* suffix)
    152     : ScratchFile(other.GetFilename() + suffix) {}
    153 
    154 ScratchFile::ScratchFile(const std::string& filename) : filename_(filename) {
    155   int fd = open(filename_.c_str(), O_RDWR | O_CREAT, 0666);
    156   CHECK_NE(-1, fd);
    157   file_.reset(new File(fd, GetFilename(), true));
    158 }
    159 
    160 ScratchFile::ScratchFile(File* file) {
    161   CHECK(file != nullptr);
    162   filename_ = file->GetPath();
    163   file_.reset(file);
    164 }
    165 
    166 ScratchFile::ScratchFile(ScratchFile&& other) {
    167   *this = std::move(other);
    168 }
    169 
    170 ScratchFile& ScratchFile::operator=(ScratchFile&& other) {
    171   if (GetFile() != other.GetFile()) {
    172     std::swap(filename_, other.filename_);
    173     std::swap(file_, other.file_);
    174   }
    175   return *this;
    176 }
    177 
    178 ScratchFile::~ScratchFile() {
    179   Unlink();
    180 }
    181 
    182 int ScratchFile::GetFd() const {
    183   return file_->Fd();
    184 }
    185 
    186 void ScratchFile::Close() {
    187   if (file_.get() != nullptr) {
    188     if (file_->FlushCloseOrErase() != 0) {
    189       PLOG(WARNING) << "Error closing scratch file.";
    190     }
    191   }
    192 }
    193 
    194 void ScratchFile::Unlink() {
    195   if (!OS::FileExists(filename_.c_str())) {
    196     return;
    197   }
    198   Close();
    199   int unlink_result = unlink(filename_.c_str());
    200   CHECK_EQ(0, unlink_result);
    201 }
    202 
    203 static bool unstarted_initialized_ = false;
    204 
    205 CommonRuntimeTestImpl::CommonRuntimeTestImpl()
    206     : class_linker_(nullptr), java_lang_dex_file_(nullptr) {
    207 }
    208 
    209 CommonRuntimeTestImpl::~CommonRuntimeTestImpl() {
    210   // Ensure the dex files are cleaned up before the runtime.
    211   loaded_dex_files_.clear();
    212   runtime_.reset();
    213 }
    214 
    215 void CommonRuntimeTestImpl::SetUpAndroidRoot() {
    216   if (IsHost()) {
    217     // $ANDROID_ROOT is set on the device, but not necessarily on the host.
    218     // But it needs to be set so that icu4c can find its locale data.
    219     const char* android_root_from_env = getenv("ANDROID_ROOT");
    220     if (android_root_from_env == nullptr) {
    221       // Use ANDROID_HOST_OUT for ANDROID_ROOT if it is set.
    222       const char* android_host_out = getenv("ANDROID_HOST_OUT");
    223       if (android_host_out != nullptr) {
    224         setenv("ANDROID_ROOT", android_host_out, 1);
    225       } else {
    226         // Build it from ANDROID_BUILD_TOP or cwd
    227         std::string root;
    228         const char* android_build_top = getenv("ANDROID_BUILD_TOP");
    229         if (android_build_top != nullptr) {
    230           root += android_build_top;
    231         } else {
    232           // Not set by build server, so default to current directory
    233           char* cwd = getcwd(nullptr, 0);
    234           setenv("ANDROID_BUILD_TOP", cwd, 1);
    235           root += cwd;
    236           free(cwd);
    237         }
    238 #if defined(__linux__)
    239         root += "/out/host/linux-x86";
    240 #elif defined(__APPLE__)
    241         root += "/out/host/darwin-x86";
    242 #else
    243 #error unsupported OS
    244 #endif
    245         setenv("ANDROID_ROOT", root.c_str(), 1);
    246       }
    247     }
    248     setenv("LD_LIBRARY_PATH", ":", 0);  // Required by java.lang.System.<clinit>.
    249 
    250     // Not set by build server, so default
    251     if (getenv("ANDROID_HOST_OUT") == nullptr) {
    252       setenv("ANDROID_HOST_OUT", getenv("ANDROID_ROOT"), 1);
    253     }
    254   }
    255 }
    256 
    257 void CommonRuntimeTestImpl::SetUpAndroidData(std::string& android_data) {
    258   // On target, Cannot use /mnt/sdcard because it is mounted noexec, so use subdir of dalvik-cache
    259   if (IsHost()) {
    260     const char* tmpdir = getenv("TMPDIR");
    261     if (tmpdir != nullptr && tmpdir[0] != 0) {
    262       android_data = tmpdir;
    263     } else {
    264       android_data = "/tmp";
    265     }
    266   } else {
    267     android_data = "/data/dalvik-cache";
    268   }
    269   android_data += "/art-data-XXXXXX";
    270   if (mkdtemp(&android_data[0]) == nullptr) {
    271     PLOG(FATAL) << "mkdtemp(\"" << &android_data[0] << "\") failed";
    272   }
    273   setenv("ANDROID_DATA", android_data.c_str(), 1);
    274 }
    275 
    276 void CommonRuntimeTestImpl::TearDownAndroidData(const std::string& android_data,
    277                                                 bool fail_on_error) {
    278   if (fail_on_error) {
    279     ASSERT_EQ(rmdir(android_data.c_str()), 0);
    280   } else {
    281     rmdir(android_data.c_str());
    282   }
    283 }
    284 
    285 // Helper - find directory with the following format:
    286 // ${ANDROID_BUILD_TOP}/${subdir1}/${subdir2}-${version}/${subdir3}/bin/
    287 static std::string GetAndroidToolsDir(const std::string& subdir1,
    288                                       const std::string& subdir2,
    289                                       const std::string& subdir3) {
    290   std::string root;
    291   const char* android_build_top = getenv("ANDROID_BUILD_TOP");
    292   if (android_build_top != nullptr) {
    293     root = android_build_top;
    294   } else {
    295     // Not set by build server, so default to current directory
    296     char* cwd = getcwd(nullptr, 0);
    297     setenv("ANDROID_BUILD_TOP", cwd, 1);
    298     root = cwd;
    299     free(cwd);
    300   }
    301 
    302   std::string toolsdir = root + "/" + subdir1;
    303   std::string founddir;
    304   DIR* dir;
    305   if ((dir = opendir(toolsdir.c_str())) != nullptr) {
    306     float maxversion = 0;
    307     struct dirent* entry;
    308     while ((entry = readdir(dir)) != nullptr) {
    309       std::string format = subdir2 + "-%f";
    310       float version;
    311       if (std::sscanf(entry->d_name, format.c_str(), &version) == 1) {
    312         if (version > maxversion) {
    313           maxversion = version;
    314           founddir = toolsdir + "/" + entry->d_name + "/" + subdir3 + "/bin/";
    315         }
    316       }
    317     }
    318     closedir(dir);
    319   }
    320 
    321   if (founddir.empty()) {
    322     ADD_FAILURE() << "Cannot find Android tools directory.";
    323   }
    324   return founddir;
    325 }
    326 
    327 std::string CommonRuntimeTestImpl::GetAndroidHostToolsDir() {
    328   return GetAndroidToolsDir("prebuilts/gcc/linux-x86/host",
    329                             "x86_64-linux-glibc2.15",
    330                             "x86_64-linux");
    331 }
    332 
    333 std::string CommonRuntimeTestImpl::GetAndroidTargetToolsDir(InstructionSet isa) {
    334   switch (isa) {
    335     case kArm:
    336     case kThumb2:
    337       return GetAndroidToolsDir("prebuilts/gcc/linux-x86/arm",
    338                                 "arm-linux-androideabi",
    339                                 "arm-linux-androideabi");
    340     case kArm64:
    341       return GetAndroidToolsDir("prebuilts/gcc/linux-x86/aarch64",
    342                                 "aarch64-linux-android",
    343                                 "aarch64-linux-android");
    344     case kX86:
    345     case kX86_64:
    346       return GetAndroidToolsDir("prebuilts/gcc/linux-x86/x86",
    347                                 "x86_64-linux-android",
    348                                 "x86_64-linux-android");
    349     case kMips:
    350     case kMips64:
    351       return GetAndroidToolsDir("prebuilts/gcc/linux-x86/mips",
    352                                 "mips64el-linux-android",
    353                                 "mips64el-linux-android");
    354     case kNone:
    355       break;
    356   }
    357   ADD_FAILURE() << "Invalid isa " << isa;
    358   return "";
    359 }
    360 
    361 std::string CommonRuntimeTestImpl::GetCoreArtLocation() {
    362   return GetCoreFileLocation("art");
    363 }
    364 
    365 std::string CommonRuntimeTestImpl::GetCoreOatLocation() {
    366   return GetCoreFileLocation("oat");
    367 }
    368 
    369 std::unique_ptr<const DexFile> CommonRuntimeTestImpl::LoadExpectSingleDexFile(
    370     const char* location) {
    371   std::vector<std::unique_ptr<const DexFile>> dex_files;
    372   std::string error_msg;
    373   MemMap::Init();
    374   static constexpr bool kVerifyChecksum = true;
    375   if (!DexFile::Open(location, location, kVerifyChecksum, &error_msg, &dex_files)) {
    376     LOG(FATAL) << "Could not open .dex file '" << location << "': " << error_msg << "\n";
    377     UNREACHABLE();
    378   } else {
    379     CHECK_EQ(1U, dex_files.size()) << "Expected only one dex file in " << location;
    380     return std::move(dex_files[0]);
    381   }
    382 }
    383 
    384 void CommonRuntimeTestImpl::SetUp() {
    385   SetUpAndroidRoot();
    386   SetUpAndroidData(android_data_);
    387   dalvik_cache_.append(android_data_.c_str());
    388   dalvik_cache_.append("/dalvik-cache");
    389   int mkdir_result = mkdir(dalvik_cache_.c_str(), 0700);
    390   ASSERT_EQ(mkdir_result, 0);
    391 
    392   std::string min_heap_string(StringPrintf("-Xms%zdm", gc::Heap::kDefaultInitialSize / MB));
    393   std::string max_heap_string(StringPrintf("-Xmx%zdm", gc::Heap::kDefaultMaximumSize / MB));
    394 
    395 
    396   RuntimeOptions options;
    397   std::string boot_class_path_string = "-Xbootclasspath";
    398   for (const std::string &core_dex_file_name : GetLibCoreDexFileNames()) {
    399     boot_class_path_string += ":";
    400     boot_class_path_string += core_dex_file_name;
    401   }
    402 
    403   options.push_back(std::make_pair(boot_class_path_string, nullptr));
    404   options.push_back(std::make_pair("-Xcheck:jni", nullptr));
    405   options.push_back(std::make_pair(min_heap_string, nullptr));
    406   options.push_back(std::make_pair(max_heap_string, nullptr));
    407   options.push_back(std::make_pair("-XX:SlowDebug=true", nullptr));
    408   static bool gSlowDebugTestFlag = false;
    409   RegisterRuntimeDebugFlag(&gSlowDebugTestFlag);
    410 
    411   callbacks_.reset(new NoopCompilerCallbacks());
    412 
    413   SetUpRuntimeOptions(&options);
    414 
    415   // Install compiler-callbacks if SetupRuntimeOptions hasn't deleted them.
    416   if (callbacks_.get() != nullptr) {
    417     options.push_back(std::make_pair("compilercallbacks", callbacks_.get()));
    418   }
    419 
    420   PreRuntimeCreate();
    421   if (!Runtime::Create(options, false)) {
    422     LOG(FATAL) << "Failed to create runtime";
    423     return;
    424   }
    425   PostRuntimeCreate();
    426   runtime_.reset(Runtime::Current());
    427   class_linker_ = runtime_->GetClassLinker();
    428 
    429   // Runtime::Create acquired the mutator_lock_ that is normally given away when we
    430   // Runtime::Start, give it away now and then switch to a more managable ScopedObjectAccess.
    431   Thread::Current()->TransitionFromRunnableToSuspended(kNative);
    432 
    433   // Get the boot class path from the runtime so it can be used in tests.
    434   boot_class_path_ = class_linker_->GetBootClassPath();
    435   ASSERT_FALSE(boot_class_path_.empty());
    436   java_lang_dex_file_ = boot_class_path_[0];
    437 
    438   FinalizeSetup();
    439 
    440   // Ensure that we're really running with debug checks enabled.
    441   CHECK(gSlowDebugTestFlag);
    442 }
    443 
    444 void CommonRuntimeTestImpl::FinalizeSetup() {
    445   // Initialize maps for unstarted runtime. This needs to be here, as running clinits needs this
    446   // set up.
    447   if (!unstarted_initialized_) {
    448     interpreter::UnstartedRuntime::Initialize();
    449     unstarted_initialized_ = true;
    450   }
    451 
    452   {
    453     ScopedObjectAccess soa(Thread::Current());
    454     class_linker_->RunRootClinits();
    455   }
    456 
    457   // We're back in native, take the opportunity to initialize well known classes.
    458   WellKnownClasses::Init(Thread::Current()->GetJniEnv());
    459 
    460   // Create the heap thread pool so that the GC runs in parallel for tests. Normally, the thread
    461   // pool is created by the runtime.
    462   runtime_->GetHeap()->CreateThreadPool();
    463   runtime_->GetHeap()->VerifyHeap();  // Check for heap corruption before the test
    464   // Reduce timinig-dependent flakiness in OOME behavior (eg StubTest.AllocObject).
    465   runtime_->GetHeap()->SetMinIntervalHomogeneousSpaceCompactionByOom(0U);
    466 }
    467 
    468 void CommonRuntimeTestImpl::ClearDirectory(const char* dirpath, bool recursive) {
    469   ASSERT_TRUE(dirpath != nullptr);
    470   DIR* dir = opendir(dirpath);
    471   ASSERT_TRUE(dir != nullptr);
    472   dirent* e;
    473   struct stat s;
    474   while ((e = readdir(dir)) != nullptr) {
    475     if ((strcmp(e->d_name, ".") == 0) || (strcmp(e->d_name, "..") == 0)) {
    476       continue;
    477     }
    478     std::string filename(dirpath);
    479     filename.push_back('/');
    480     filename.append(e->d_name);
    481     int stat_result = lstat(filename.c_str(), &s);
    482     ASSERT_EQ(0, stat_result) << "unable to stat " << filename;
    483     if (S_ISDIR(s.st_mode)) {
    484       if (recursive) {
    485         ClearDirectory(filename.c_str());
    486         int rmdir_result = rmdir(filename.c_str());
    487         ASSERT_EQ(0, rmdir_result) << filename;
    488       }
    489     } else {
    490       int unlink_result = unlink(filename.c_str());
    491       ASSERT_EQ(0, unlink_result) << filename;
    492     }
    493   }
    494   closedir(dir);
    495 }
    496 
    497 void CommonRuntimeTestImpl::TearDown() {
    498   const char* android_data = getenv("ANDROID_DATA");
    499   ASSERT_TRUE(android_data != nullptr);
    500   ClearDirectory(dalvik_cache_.c_str());
    501   int rmdir_cache_result = rmdir(dalvik_cache_.c_str());
    502   ASSERT_EQ(0, rmdir_cache_result);
    503   TearDownAndroidData(android_data_, true);
    504   dalvik_cache_.clear();
    505 
    506   if (runtime_ != nullptr) {
    507     runtime_->GetHeap()->VerifyHeap();  // Check for heap corruption after the test
    508   }
    509 }
    510 
    511 static std::string GetDexFileName(const std::string& jar_prefix, bool host) {
    512   std::string path;
    513   if (host) {
    514     const char* host_dir = getenv("ANDROID_HOST_OUT");
    515     CHECK(host_dir != nullptr);
    516     path = host_dir;
    517   } else {
    518     path = GetAndroidRoot();
    519   }
    520 
    521   std::string suffix = host
    522       ? "-hostdex"                 // The host version.
    523       : "-testdex";                // The unstripped target version.
    524 
    525   return StringPrintf("%s/framework/%s%s.jar", path.c_str(), jar_prefix.c_str(), suffix.c_str());
    526 }
    527 
    528 std::vector<std::string> CommonRuntimeTestImpl::GetLibCoreDexFileNames() {
    529   return std::vector<std::string>({GetDexFileName("core-oj", IsHost()),
    530                                    GetDexFileName("core-libart", IsHost())});
    531 }
    532 
    533 std::string CommonRuntimeTestImpl::GetTestAndroidRoot() {
    534   if (IsHost()) {
    535     const char* host_dir = getenv("ANDROID_HOST_OUT");
    536     CHECK(host_dir != nullptr);
    537     return host_dir;
    538   }
    539   return GetAndroidRoot();
    540 }
    541 
    542 // Check that for target builds we have ART_TARGET_NATIVETEST_DIR set.
    543 #ifdef ART_TARGET
    544 #ifndef ART_TARGET_NATIVETEST_DIR
    545 #error "ART_TARGET_NATIVETEST_DIR not set."
    546 #endif
    547 // Wrap it as a string literal.
    548 #define ART_TARGET_NATIVETEST_DIR_STRING STRINGIFY(ART_TARGET_NATIVETEST_DIR) "/"
    549 #else
    550 #define ART_TARGET_NATIVETEST_DIR_STRING ""
    551 #endif
    552 
    553 std::string CommonRuntimeTestImpl::GetTestDexFileName(const char* name) const {
    554   CHECK(name != nullptr);
    555   std::string filename;
    556   if (IsHost()) {
    557     filename += getenv("ANDROID_HOST_OUT");
    558     filename += "/framework/";
    559   } else {
    560     filename += ART_TARGET_NATIVETEST_DIR_STRING;
    561   }
    562   filename += "art-gtest-";
    563   filename += name;
    564   filename += ".jar";
    565   return filename;
    566 }
    567 
    568 std::vector<std::unique_ptr<const DexFile>> CommonRuntimeTestImpl::OpenTestDexFiles(
    569     const char* name) {
    570   std::string filename = GetTestDexFileName(name);
    571   static constexpr bool kVerifyChecksum = true;
    572   std::string error_msg;
    573   std::vector<std::unique_ptr<const DexFile>> dex_files;
    574   bool success = DexFile::Open(
    575       filename.c_str(), filename.c_str(), kVerifyChecksum, &error_msg, &dex_files);
    576   CHECK(success) << "Failed to open '" << filename << "': " << error_msg;
    577   for (auto& dex_file : dex_files) {
    578     CHECK_EQ(PROT_READ, dex_file->GetPermissions());
    579     CHECK(dex_file->IsReadOnly());
    580   }
    581   return dex_files;
    582 }
    583 
    584 std::unique_ptr<const DexFile> CommonRuntimeTestImpl::OpenTestDexFile(const char* name) {
    585   std::vector<std::unique_ptr<const DexFile>> vector = OpenTestDexFiles(name);
    586   EXPECT_EQ(1U, vector.size());
    587   return std::move(vector[0]);
    588 }
    589 
    590 std::vector<const DexFile*> CommonRuntimeTestImpl::GetDexFiles(jobject jclass_loader) {
    591   ScopedObjectAccess soa(Thread::Current());
    592 
    593   StackHandleScope<1> hs(soa.Self());
    594   Handle<mirror::ClassLoader> class_loader = hs.NewHandle(
    595       soa.Decode<mirror::ClassLoader>(jclass_loader));
    596   return GetDexFiles(soa, class_loader);
    597 }
    598 
    599 std::vector<const DexFile*> CommonRuntimeTestImpl::GetDexFiles(
    600     ScopedObjectAccess& soa,
    601     Handle<mirror::ClassLoader> class_loader) {
    602   std::vector<const DexFile*> ret;
    603 
    604   DCHECK(
    605       (class_loader->GetClass() ==
    606           soa.Decode<mirror::Class>(WellKnownClasses::dalvik_system_PathClassLoader)) ||
    607       (class_loader->GetClass() ==
    608           soa.Decode<mirror::Class>(WellKnownClasses::dalvik_system_DelegateLastClassLoader)));
    609 
    610   // The class loader is a PathClassLoader which inherits from BaseDexClassLoader.
    611   // We need to get the DexPathList and loop through it.
    612   ArtField* cookie_field = jni::DecodeArtField(WellKnownClasses::dalvik_system_DexFile_cookie);
    613   ArtField* dex_file_field =
    614       jni::DecodeArtField(WellKnownClasses::dalvik_system_DexPathList__Element_dexFile);
    615   ObjPtr<mirror::Object> dex_path_list =
    616       jni::DecodeArtField(WellKnownClasses::dalvik_system_BaseDexClassLoader_pathList)->
    617           GetObject(class_loader.Get());
    618   if (dex_path_list != nullptr && dex_file_field!= nullptr && cookie_field != nullptr) {
    619     // DexPathList has an array dexElements of Elements[] which each contain a dex file.
    620     ObjPtr<mirror::Object> dex_elements_obj =
    621         jni::DecodeArtField(WellKnownClasses::dalvik_system_DexPathList_dexElements)->
    622             GetObject(dex_path_list);
    623     // Loop through each dalvik.system.DexPathList$Element's dalvik.system.DexFile and look
    624     // at the mCookie which is a DexFile vector.
    625     if (dex_elements_obj != nullptr) {
    626       StackHandleScope<1> hs(soa.Self());
    627       Handle<mirror::ObjectArray<mirror::Object>> dex_elements =
    628           hs.NewHandle(dex_elements_obj->AsObjectArray<mirror::Object>());
    629       for (int32_t i = 0; i < dex_elements->GetLength(); ++i) {
    630         ObjPtr<mirror::Object> element = dex_elements->GetWithoutChecks(i);
    631         if (element == nullptr) {
    632           // Should never happen, fall back to java code to throw a NPE.
    633           break;
    634         }
    635         ObjPtr<mirror::Object> dex_file = dex_file_field->GetObject(element);
    636         if (dex_file != nullptr) {
    637           ObjPtr<mirror::LongArray> long_array = cookie_field->GetObject(dex_file)->AsLongArray();
    638           DCHECK(long_array != nullptr);
    639           int32_t long_array_size = long_array->GetLength();
    640           for (int32_t j = kDexFileIndexStart; j < long_array_size; ++j) {
    641             const DexFile* cp_dex_file = reinterpret_cast<const DexFile*>(static_cast<uintptr_t>(
    642                 long_array->GetWithoutChecks(j)));
    643             if (cp_dex_file == nullptr) {
    644               LOG(WARNING) << "Null DexFile";
    645               continue;
    646             }
    647             ret.push_back(cp_dex_file);
    648           }
    649         }
    650       }
    651     }
    652   }
    653 
    654   return ret;
    655 }
    656 
    657 const DexFile* CommonRuntimeTestImpl::GetFirstDexFile(jobject jclass_loader) {
    658   std::vector<const DexFile*> tmp(GetDexFiles(jclass_loader));
    659   DCHECK(!tmp.empty());
    660   const DexFile* ret = tmp[0];
    661   DCHECK(ret != nullptr);
    662   return ret;
    663 }
    664 
    665 jobject CommonRuntimeTestImpl::LoadMultiDex(const char* first_dex_name,
    666                                             const char* second_dex_name) {
    667   std::vector<std::unique_ptr<const DexFile>> first_dex_files = OpenTestDexFiles(first_dex_name);
    668   std::vector<std::unique_ptr<const DexFile>> second_dex_files = OpenTestDexFiles(second_dex_name);
    669   std::vector<const DexFile*> class_path;
    670   CHECK_NE(0U, first_dex_files.size());
    671   CHECK_NE(0U, second_dex_files.size());
    672   for (auto& dex_file : first_dex_files) {
    673     class_path.push_back(dex_file.get());
    674     loaded_dex_files_.push_back(std::move(dex_file));
    675   }
    676   for (auto& dex_file : second_dex_files) {
    677     class_path.push_back(dex_file.get());
    678     loaded_dex_files_.push_back(std::move(dex_file));
    679   }
    680 
    681   Thread* self = Thread::Current();
    682   jobject class_loader = Runtime::Current()->GetClassLinker()->CreatePathClassLoader(self,
    683                                                                                      class_path);
    684   self->SetClassLoaderOverride(class_loader);
    685   return class_loader;
    686 }
    687 
    688 jobject CommonRuntimeTestImpl::LoadDex(const char* dex_name) {
    689   jobject class_loader = LoadDexInPathClassLoader(dex_name, nullptr);
    690   Thread::Current()->SetClassLoaderOverride(class_loader);
    691   return class_loader;
    692 }
    693 
    694 jobject CommonRuntimeTestImpl::LoadDexInWellKnownClassLoader(const std::string& dex_name,
    695                                                              jclass loader_class,
    696                                                              jobject parent_loader) {
    697   std::vector<std::unique_ptr<const DexFile>> dex_files = OpenTestDexFiles(dex_name.c_str());
    698   std::vector<const DexFile*> class_path;
    699   CHECK_NE(0U, dex_files.size());
    700   for (auto& dex_file : dex_files) {
    701     class_path.push_back(dex_file.get());
    702     loaded_dex_files_.push_back(std::move(dex_file));
    703   }
    704   Thread* self = Thread::Current();
    705   ScopedObjectAccess soa(self);
    706 
    707   jobject result = Runtime::Current()->GetClassLinker()->CreateWellKnownClassLoader(
    708       self,
    709       class_path,
    710       loader_class,
    711       parent_loader);
    712 
    713   {
    714     // Verify we build the correct chain.
    715 
    716     ObjPtr<mirror::ClassLoader> actual_class_loader = soa.Decode<mirror::ClassLoader>(result);
    717     // Verify that the result has the correct class.
    718     CHECK_EQ(soa.Decode<mirror::Class>(loader_class), actual_class_loader->GetClass());
    719     // Verify that the parent is not null. The boot class loader will be set up as a
    720     // proper object.
    721     ObjPtr<mirror::ClassLoader> actual_parent(actual_class_loader->GetParent());
    722     CHECK(actual_parent != nullptr);
    723 
    724     if (parent_loader != nullptr) {
    725       // We were given a parent. Verify that it's what we expect.
    726       ObjPtr<mirror::ClassLoader> expected_parent = soa.Decode<mirror::ClassLoader>(parent_loader);
    727       CHECK_EQ(expected_parent, actual_parent);
    728     } else {
    729       // No parent given. The parent must be the BootClassLoader.
    730       CHECK(Runtime::Current()->GetClassLinker()->IsBootClassLoader(soa, actual_parent));
    731     }
    732   }
    733 
    734   return result;
    735 }
    736 
    737 jobject CommonRuntimeTestImpl::LoadDexInPathClassLoader(const std::string& dex_name,
    738                                                         jobject parent_loader) {
    739   return LoadDexInWellKnownClassLoader(dex_name,
    740                                        WellKnownClasses::dalvik_system_PathClassLoader,
    741                                        parent_loader);
    742 }
    743 
    744 jobject CommonRuntimeTestImpl::LoadDexInDelegateLastClassLoader(const std::string& dex_name,
    745                                                                 jobject parent_loader) {
    746   return LoadDexInWellKnownClassLoader(dex_name,
    747                                        WellKnownClasses::dalvik_system_DelegateLastClassLoader,
    748                                        parent_loader);
    749 }
    750 
    751 std::string CommonRuntimeTestImpl::GetCoreFileLocation(const char* suffix) {
    752   CHECK(suffix != nullptr);
    753 
    754   std::string location;
    755   if (IsHost()) {
    756     const char* host_dir = getenv("ANDROID_HOST_OUT");
    757     CHECK(host_dir != nullptr);
    758     location = StringPrintf("%s/framework/core.%s", host_dir, suffix);
    759   } else {
    760     location = StringPrintf("/data/art-test/core.%s", suffix);
    761   }
    762 
    763   return location;
    764 }
    765 
    766 std::string CommonRuntimeTestImpl::CreateClassPath(
    767     const std::vector<std::unique_ptr<const DexFile>>& dex_files) {
    768   CHECK(!dex_files.empty());
    769   std::string classpath = dex_files[0]->GetLocation();
    770   for (size_t i = 1; i < dex_files.size(); i++) {
    771     classpath += ":" + dex_files[i]->GetLocation();
    772   }
    773   return classpath;
    774 }
    775 
    776 std::string CommonRuntimeTestImpl::CreateClassPathWithChecksums(
    777     const std::vector<std::unique_ptr<const DexFile>>& dex_files) {
    778   CHECK(!dex_files.empty());
    779   std::string classpath = dex_files[0]->GetLocation() + "*" +
    780       std::to_string(dex_files[0]->GetLocationChecksum());
    781   for (size_t i = 1; i < dex_files.size(); i++) {
    782     classpath += ":" + dex_files[i]->GetLocation() + "*" +
    783         std::to_string(dex_files[i]->GetLocationChecksum());
    784   }
    785   return classpath;
    786 }
    787 
    788 CheckJniAbortCatcher::CheckJniAbortCatcher() : vm_(Runtime::Current()->GetJavaVM()) {
    789   vm_->SetCheckJniAbortHook(Hook, &actual_);
    790 }
    791 
    792 CheckJniAbortCatcher::~CheckJniAbortCatcher() {
    793   vm_->SetCheckJniAbortHook(nullptr, nullptr);
    794   EXPECT_TRUE(actual_.empty()) << actual_;
    795 }
    796 
    797 void CheckJniAbortCatcher::Check(const std::string& expected_text) {
    798   Check(expected_text.c_str());
    799 }
    800 
    801 void CheckJniAbortCatcher::Check(const char* expected_text) {
    802   EXPECT_TRUE(actual_.find(expected_text) != std::string::npos) << "\n"
    803       << "Expected to find: " << expected_text << "\n"
    804       << "In the output   : " << actual_;
    805   actual_.clear();
    806 }
    807 
    808 void CheckJniAbortCatcher::Hook(void* data, const std::string& reason) {
    809   // We use += because when we're hooking the aborts like this, multiple problems can be found.
    810   *reinterpret_cast<std::string*>(data) += reason;
    811 }
    812 
    813 }  // namespace art
    814