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 <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/macros.h"
     31 #include "base/logging.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_root-inl.h"
     38 #include "gc/heap.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 "mirror/class-inl.h"
     45 #include "mirror/class_loader.h"
     46 #include "mem_map.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::Aborter);
     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 
    408   callbacks_.reset(new NoopCompilerCallbacks());
    409 
    410   SetUpRuntimeOptions(&options);
    411 
    412   // Install compiler-callbacks if SetupRuntimeOptions hasn't deleted them.
    413   if (callbacks_.get() != nullptr) {
    414     options.push_back(std::make_pair("compilercallbacks", callbacks_.get()));
    415   }
    416 
    417   PreRuntimeCreate();
    418   if (!Runtime::Create(options, false)) {
    419     LOG(FATAL) << "Failed to create runtime";
    420     return;
    421   }
    422   PostRuntimeCreate();
    423   runtime_.reset(Runtime::Current());
    424   class_linker_ = runtime_->GetClassLinker();
    425   class_linker_->FixupDexCaches(runtime_->GetResolutionMethod());
    426 
    427   // Runtime::Create acquired the mutator_lock_ that is normally given away when we
    428   // Runtime::Start, give it away now and then switch to a more managable ScopedObjectAccess.
    429   Thread::Current()->TransitionFromRunnableToSuspended(kNative);
    430 
    431   // Get the boot class path from the runtime so it can be used in tests.
    432   boot_class_path_ = class_linker_->GetBootClassPath();
    433   ASSERT_FALSE(boot_class_path_.empty());
    434   java_lang_dex_file_ = boot_class_path_[0];
    435 
    436   FinalizeSetup();
    437 }
    438 
    439 void CommonRuntimeTestImpl::FinalizeSetup() {
    440   // Initialize maps for unstarted runtime. This needs to be here, as running clinits needs this
    441   // set up.
    442   if (!unstarted_initialized_) {
    443     interpreter::UnstartedRuntime::Initialize();
    444     unstarted_initialized_ = true;
    445   }
    446 
    447   {
    448     ScopedObjectAccess soa(Thread::Current());
    449     class_linker_->RunRootClinits();
    450   }
    451 
    452   // We're back in native, take the opportunity to initialize well known classes.
    453   WellKnownClasses::Init(Thread::Current()->GetJniEnv());
    454 
    455   // Create the heap thread pool so that the GC runs in parallel for tests. Normally, the thread
    456   // pool is created by the runtime.
    457   runtime_->GetHeap()->CreateThreadPool();
    458   runtime_->GetHeap()->VerifyHeap();  // Check for heap corruption before the test
    459   // Reduce timinig-dependent flakiness in OOME behavior (eg StubTest.AllocObject).
    460   runtime_->GetHeap()->SetMinIntervalHomogeneousSpaceCompactionByOom(0U);
    461 }
    462 
    463 void CommonRuntimeTestImpl::ClearDirectory(const char* dirpath) {
    464   ASSERT_TRUE(dirpath != nullptr);
    465   DIR* dir = opendir(dirpath);
    466   ASSERT_TRUE(dir != nullptr);
    467   dirent* e;
    468   struct stat s;
    469   while ((e = readdir(dir)) != nullptr) {
    470     if ((strcmp(e->d_name, ".") == 0) || (strcmp(e->d_name, "..") == 0)) {
    471       continue;
    472     }
    473     std::string filename(dirpath);
    474     filename.push_back('/');
    475     filename.append(e->d_name);
    476     int stat_result = lstat(filename.c_str(), &s);
    477     ASSERT_EQ(0, stat_result) << "unable to stat " << filename;
    478     if (S_ISDIR(s.st_mode)) {
    479       ClearDirectory(filename.c_str());
    480       int rmdir_result = rmdir(filename.c_str());
    481       ASSERT_EQ(0, rmdir_result) << filename;
    482     } else {
    483       int unlink_result = unlink(filename.c_str());
    484       ASSERT_EQ(0, unlink_result) << filename;
    485     }
    486   }
    487   closedir(dir);
    488 }
    489 
    490 void CommonRuntimeTestImpl::TearDown() {
    491   const char* android_data = getenv("ANDROID_DATA");
    492   ASSERT_TRUE(android_data != nullptr);
    493   ClearDirectory(dalvik_cache_.c_str());
    494   int rmdir_cache_result = rmdir(dalvik_cache_.c_str());
    495   ASSERT_EQ(0, rmdir_cache_result);
    496   TearDownAndroidData(android_data_, true);
    497   dalvik_cache_.clear();
    498 
    499   if (runtime_ != nullptr) {
    500     runtime_->GetHeap()->VerifyHeap();  // Check for heap corruption after the test
    501   }
    502 }
    503 
    504 static std::string GetDexFileName(const std::string& jar_prefix, bool host) {
    505   std::string path;
    506   if (host) {
    507     const char* host_dir = getenv("ANDROID_HOST_OUT");
    508     CHECK(host_dir != nullptr);
    509     path = host_dir;
    510   } else {
    511     path = GetAndroidRoot();
    512   }
    513 
    514   std::string suffix = host
    515       ? "-hostdex"                 // The host version.
    516       : "-testdex";                // The unstripped target version.
    517 
    518   return StringPrintf("%s/framework/%s%s.jar", path.c_str(), jar_prefix.c_str(), suffix.c_str());
    519 }
    520 
    521 std::vector<std::string> CommonRuntimeTestImpl::GetLibCoreDexFileNames() {
    522   return std::vector<std::string>({GetDexFileName("core-oj", IsHost()),
    523                                    GetDexFileName("core-libart", IsHost())});
    524 }
    525 
    526 std::string CommonRuntimeTestImpl::GetTestAndroidRoot() {
    527   if (IsHost()) {
    528     const char* host_dir = getenv("ANDROID_HOST_OUT");
    529     CHECK(host_dir != nullptr);
    530     return host_dir;
    531   }
    532   return GetAndroidRoot();
    533 }
    534 
    535 // Check that for target builds we have ART_TARGET_NATIVETEST_DIR set.
    536 #ifdef ART_TARGET
    537 #ifndef ART_TARGET_NATIVETEST_DIR
    538 #error "ART_TARGET_NATIVETEST_DIR not set."
    539 #endif
    540 // Wrap it as a string literal.
    541 #define ART_TARGET_NATIVETEST_DIR_STRING STRINGIFY(ART_TARGET_NATIVETEST_DIR) "/"
    542 #else
    543 #define ART_TARGET_NATIVETEST_DIR_STRING ""
    544 #endif
    545 
    546 std::string CommonRuntimeTestImpl::GetTestDexFileName(const char* name) const {
    547   CHECK(name != nullptr);
    548   std::string filename;
    549   if (IsHost()) {
    550     filename += getenv("ANDROID_HOST_OUT");
    551     filename += "/framework/";
    552   } else {
    553     filename += ART_TARGET_NATIVETEST_DIR_STRING;
    554   }
    555   filename += "art-gtest-";
    556   filename += name;
    557   filename += ".jar";
    558   return filename;
    559 }
    560 
    561 std::vector<std::unique_ptr<const DexFile>> CommonRuntimeTestImpl::OpenTestDexFiles(
    562     const char* name) {
    563   std::string filename = GetTestDexFileName(name);
    564   static constexpr bool kVerifyChecksum = true;
    565   std::string error_msg;
    566   std::vector<std::unique_ptr<const DexFile>> dex_files;
    567   bool success = DexFile::Open(
    568       filename.c_str(), filename.c_str(), kVerifyChecksum, &error_msg, &dex_files);
    569   CHECK(success) << "Failed to open '" << filename << "': " << error_msg;
    570   for (auto& dex_file : dex_files) {
    571     CHECK_EQ(PROT_READ, dex_file->GetPermissions());
    572     CHECK(dex_file->IsReadOnly());
    573   }
    574   return dex_files;
    575 }
    576 
    577 std::unique_ptr<const DexFile> CommonRuntimeTestImpl::OpenTestDexFile(const char* name) {
    578   std::vector<std::unique_ptr<const DexFile>> vector = OpenTestDexFiles(name);
    579   EXPECT_EQ(1U, vector.size());
    580   return std::move(vector[0]);
    581 }
    582 
    583 std::vector<const DexFile*> CommonRuntimeTestImpl::GetDexFiles(jobject jclass_loader) {
    584   std::vector<const DexFile*> ret;
    585 
    586   ScopedObjectAccess soa(Thread::Current());
    587 
    588   StackHandleScope<2> hs(soa.Self());
    589   Handle<mirror::ClassLoader> class_loader = hs.NewHandle(
    590       soa.Decode<mirror::ClassLoader>(jclass_loader));
    591 
    592   DCHECK_EQ(class_loader->GetClass(),
    593             soa.Decode<mirror::Class>(WellKnownClasses::dalvik_system_PathClassLoader));
    594   DCHECK_EQ(class_loader->GetParent()->GetClass(),
    595             soa.Decode<mirror::Class>(WellKnownClasses::java_lang_BootClassLoader));
    596 
    597   // The class loader is a PathClassLoader which inherits from BaseDexClassLoader.
    598   // We need to get the DexPathList and loop through it.
    599   ArtField* cookie_field = jni::DecodeArtField(WellKnownClasses::dalvik_system_DexFile_cookie);
    600   ArtField* dex_file_field =
    601       jni::DecodeArtField(WellKnownClasses::dalvik_system_DexPathList__Element_dexFile);
    602   ObjPtr<mirror::Object> dex_path_list =
    603       jni::DecodeArtField(WellKnownClasses::dalvik_system_BaseDexClassLoader_pathList)->
    604           GetObject(class_loader.Get());
    605   if (dex_path_list != nullptr && dex_file_field!= nullptr && cookie_field != nullptr) {
    606     // DexPathList has an array dexElements of Elements[] which each contain a dex file.
    607     ObjPtr<mirror::Object> dex_elements_obj =
    608         jni::DecodeArtField(WellKnownClasses::dalvik_system_DexPathList_dexElements)->
    609             GetObject(dex_path_list);
    610     // Loop through each dalvik.system.DexPathList$Element's dalvik.system.DexFile and look
    611     // at the mCookie which is a DexFile vector.
    612     if (dex_elements_obj != nullptr) {
    613       Handle<mirror::ObjectArray<mirror::Object>> dex_elements =
    614           hs.NewHandle(dex_elements_obj->AsObjectArray<mirror::Object>());
    615       for (int32_t i = 0; i < dex_elements->GetLength(); ++i) {
    616         ObjPtr<mirror::Object> element = dex_elements->GetWithoutChecks(i);
    617         if (element == nullptr) {
    618           // Should never happen, fall back to java code to throw a NPE.
    619           break;
    620         }
    621         ObjPtr<mirror::Object> dex_file = dex_file_field->GetObject(element);
    622         if (dex_file != nullptr) {
    623           ObjPtr<mirror::LongArray> long_array = cookie_field->GetObject(dex_file)->AsLongArray();
    624           DCHECK(long_array != nullptr);
    625           int32_t long_array_size = long_array->GetLength();
    626           for (int32_t j = kDexFileIndexStart; j < long_array_size; ++j) {
    627             const DexFile* cp_dex_file = reinterpret_cast<const DexFile*>(static_cast<uintptr_t>(
    628                 long_array->GetWithoutChecks(j)));
    629             if (cp_dex_file == nullptr) {
    630               LOG(WARNING) << "Null DexFile";
    631               continue;
    632             }
    633             ret.push_back(cp_dex_file);
    634           }
    635         }
    636       }
    637     }
    638   }
    639 
    640   return ret;
    641 }
    642 
    643 const DexFile* CommonRuntimeTestImpl::GetFirstDexFile(jobject jclass_loader) {
    644   std::vector<const DexFile*> tmp(GetDexFiles(jclass_loader));
    645   DCHECK(!tmp.empty());
    646   const DexFile* ret = tmp[0];
    647   DCHECK(ret != nullptr);
    648   return ret;
    649 }
    650 
    651 jobject CommonRuntimeTestImpl::LoadMultiDex(const char* first_dex_name,
    652                                             const char* second_dex_name) {
    653   std::vector<std::unique_ptr<const DexFile>> first_dex_files = OpenTestDexFiles(first_dex_name);
    654   std::vector<std::unique_ptr<const DexFile>> second_dex_files = OpenTestDexFiles(second_dex_name);
    655   std::vector<const DexFile*> class_path;
    656   CHECK_NE(0U, first_dex_files.size());
    657   CHECK_NE(0U, second_dex_files.size());
    658   for (auto& dex_file : first_dex_files) {
    659     class_path.push_back(dex_file.get());
    660     loaded_dex_files_.push_back(std::move(dex_file));
    661   }
    662   for (auto& dex_file : second_dex_files) {
    663     class_path.push_back(dex_file.get());
    664     loaded_dex_files_.push_back(std::move(dex_file));
    665   }
    666 
    667   Thread* self = Thread::Current();
    668   jobject class_loader = Runtime::Current()->GetClassLinker()->CreatePathClassLoader(self,
    669                                                                                      class_path);
    670   self->SetClassLoaderOverride(class_loader);
    671   return class_loader;
    672 }
    673 
    674 jobject CommonRuntimeTestImpl::LoadDex(const char* dex_name) {
    675   std::vector<std::unique_ptr<const DexFile>> dex_files = OpenTestDexFiles(dex_name);
    676   std::vector<const DexFile*> class_path;
    677   CHECK_NE(0U, dex_files.size());
    678   for (auto& dex_file : dex_files) {
    679     class_path.push_back(dex_file.get());
    680     loaded_dex_files_.push_back(std::move(dex_file));
    681   }
    682 
    683   Thread* self = Thread::Current();
    684   jobject class_loader = Runtime::Current()->GetClassLinker()->CreatePathClassLoader(self,
    685                                                                                      class_path);
    686   self->SetClassLoaderOverride(class_loader);
    687   return class_loader;
    688 }
    689 
    690 std::string CommonRuntimeTestImpl::GetCoreFileLocation(const char* suffix) {
    691   CHECK(suffix != nullptr);
    692 
    693   std::string location;
    694   if (IsHost()) {
    695     const char* host_dir = getenv("ANDROID_HOST_OUT");
    696     CHECK(host_dir != nullptr);
    697     location = StringPrintf("%s/framework/core.%s", host_dir, suffix);
    698   } else {
    699     location = StringPrintf("/data/art-test/core.%s", suffix);
    700   }
    701 
    702   return location;
    703 }
    704 
    705 CheckJniAbortCatcher::CheckJniAbortCatcher() : vm_(Runtime::Current()->GetJavaVM()) {
    706   vm_->SetCheckJniAbortHook(Hook, &actual_);
    707 }
    708 
    709 CheckJniAbortCatcher::~CheckJniAbortCatcher() {
    710   vm_->SetCheckJniAbortHook(nullptr, nullptr);
    711   EXPECT_TRUE(actual_.empty()) << actual_;
    712 }
    713 
    714 void CheckJniAbortCatcher::Check(const std::string& expected_text) {
    715   Check(expected_text.c_str());
    716 }
    717 
    718 void CheckJniAbortCatcher::Check(const char* expected_text) {
    719   EXPECT_TRUE(actual_.find(expected_text) != std::string::npos) << "\n"
    720       << "Expected to find: " << expected_text << "\n"
    721       << "In the output   : " << actual_;
    722   actual_.clear();
    723 }
    724 
    725 void CheckJniAbortCatcher::Hook(void* data, const std::string& reason) {
    726   // We use += because when we're hooking the aborts like this, multiple problems can be found.
    727   *reinterpret_cast<std::string*>(data) += reason;
    728 }
    729 
    730 }  // namespace art
    731 
    732 namespace std {
    733 
    734 template <typename T>
    735 std::ostream& operator<<(std::ostream& os, const std::vector<T>& rhs) {
    736 os << ::art::ToString(rhs);
    737 return os;
    738 }
    739 
    740 }  // namespace std
    741