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 <dirent.h>
     20 #include <dlfcn.h>
     21 #include <fcntl.h>
     22 #include <stdlib.h>
     23 #include <cstdio>
     24 #include "nativehelper/scoped_local_ref.h"
     25 
     26 #include "android-base/stringprintf.h"
     27 
     28 #include "art_field-inl.h"
     29 #include "base/file_utils.h"
     30 #include "base/logging.h"
     31 #include "base/macros.h"
     32 #include "base/mem_map.h"
     33 #include "base/mutex.h"
     34 #include "base/os.h"
     35 #include "base/runtime_debug.h"
     36 #include "base/stl_util.h"
     37 #include "base/unix_file/fd_file.h"
     38 #include "class_linker.h"
     39 #include "class_loader_utils.h"
     40 #include "compiler_callbacks.h"
     41 #include "dex/art_dex_file_loader.h"
     42 #include "dex/dex_file-inl.h"
     43 #include "dex/dex_file_loader.h"
     44 #include "dex/primitive.h"
     45 #include "gc/heap.h"
     46 #include "gc/space/image_space.h"
     47 #include "gc_root-inl.h"
     48 #include "gtest/gtest.h"
     49 #include "handle_scope-inl.h"
     50 #include "interpreter/unstarted_runtime.h"
     51 #include "jni/java_vm_ext.h"
     52 #include "jni/jni_internal.h"
     53 #include "mirror/class-alloc-inl.h"
     54 #include "mirror/class-inl.h"
     55 #include "mirror/class_loader-inl.h"
     56 #include "mirror/object_array-alloc-inl.h"
     57 #include "native/dalvik_system_DexFile.h"
     58 #include "noop_compiler_callbacks.h"
     59 #include "runtime-inl.h"
     60 #include "scoped_thread_state_change-inl.h"
     61 #include "thread.h"
     62 #include "well_known_classes.h"
     63 
     64 namespace art {
     65 
     66 using android::base::StringPrintf;
     67 
     68 static bool unstarted_initialized_ = false;
     69 
     70 CommonRuntimeTestImpl::CommonRuntimeTestImpl()
     71     : class_linker_(nullptr), java_lang_dex_file_(nullptr) {
     72 }
     73 
     74 CommonRuntimeTestImpl::~CommonRuntimeTestImpl() {
     75   // Ensure the dex files are cleaned up before the runtime.
     76   loaded_dex_files_.clear();
     77   runtime_.reset();
     78 }
     79 
     80 std::string CommonRuntimeTestImpl::GetAndroidTargetToolsDir(InstructionSet isa) {
     81   switch (isa) {
     82     case InstructionSet::kArm:
     83     case InstructionSet::kThumb2:
     84       return GetAndroidToolsDir("prebuilts/gcc/linux-x86/arm",
     85                                 "arm-linux-androideabi",
     86                                 "arm-linux-androideabi");
     87     case InstructionSet::kArm64:
     88       return GetAndroidToolsDir("prebuilts/gcc/linux-x86/aarch64",
     89                                 "aarch64-linux-android",
     90                                 "aarch64-linux-android");
     91     case InstructionSet::kX86:
     92     case InstructionSet::kX86_64:
     93       return GetAndroidToolsDir("prebuilts/gcc/linux-x86/x86",
     94                                 "x86_64-linux-android",
     95                                 "x86_64-linux-android");
     96     case InstructionSet::kMips:
     97     case InstructionSet::kMips64:
     98       return GetAndroidToolsDir("prebuilts/gcc/linux-x86/mips",
     99                                 "mips64el-linux-android",
    100                                 "mips64el-linux-android");
    101     case InstructionSet::kNone:
    102       break;
    103   }
    104   ADD_FAILURE() << "Invalid isa " << isa;
    105   return "";
    106 }
    107 
    108 void CommonRuntimeTestImpl::SetUp() {
    109   CommonArtTestImpl::SetUp();
    110 
    111   std::string min_heap_string(StringPrintf("-Xms%zdm", gc::Heap::kDefaultInitialSize / MB));
    112   std::string max_heap_string(StringPrintf("-Xmx%zdm", gc::Heap::kDefaultMaximumSize / MB));
    113 
    114   RuntimeOptions options;
    115   std::string boot_class_path_string =
    116       GetClassPathOption("-Xbootclasspath:", GetLibCoreDexFileNames());
    117   std::string boot_class_path_locations_string =
    118       GetClassPathOption("-Xbootclasspath-locations:", GetLibCoreDexLocations());
    119 
    120   options.push_back(std::make_pair(boot_class_path_string, nullptr));
    121   options.push_back(std::make_pair(boot_class_path_locations_string, nullptr));
    122   options.push_back(std::make_pair("-Xcheck:jni", nullptr));
    123   options.push_back(std::make_pair(min_heap_string, nullptr));
    124   options.push_back(std::make_pair(max_heap_string, nullptr));
    125   options.push_back(std::make_pair("-XX:SlowDebug=true", nullptr));
    126   static bool gSlowDebugTestFlag = false;
    127   RegisterRuntimeDebugFlag(&gSlowDebugTestFlag);
    128 
    129   callbacks_.reset(new NoopCompilerCallbacks());
    130 
    131   SetUpRuntimeOptions(&options);
    132 
    133   // Install compiler-callbacks if SetupRuntimeOptions hasn't deleted them.
    134   if (callbacks_.get() != nullptr) {
    135     options.push_back(std::make_pair("compilercallbacks", callbacks_.get()));
    136   }
    137 
    138   PreRuntimeCreate();
    139   if (!Runtime::Create(options, false)) {
    140     LOG(FATAL) << "Failed to create runtime";
    141     UNREACHABLE();
    142   }
    143   PostRuntimeCreate();
    144   runtime_.reset(Runtime::Current());
    145   class_linker_ = runtime_->GetClassLinker();
    146 
    147   // Runtime::Create acquired the mutator_lock_ that is normally given away when we
    148   // Runtime::Start, give it away now and then switch to a more managable ScopedObjectAccess.
    149   Thread::Current()->TransitionFromRunnableToSuspended(kNative);
    150 
    151   // Get the boot class path from the runtime so it can be used in tests.
    152   boot_class_path_ = class_linker_->GetBootClassPath();
    153   ASSERT_FALSE(boot_class_path_.empty());
    154   java_lang_dex_file_ = boot_class_path_[0];
    155 
    156   FinalizeSetup();
    157 
    158   // Ensure that we're really running with debug checks enabled.
    159   CHECK(gSlowDebugTestFlag);
    160 }
    161 
    162 void CommonRuntimeTestImpl::FinalizeSetup() {
    163   // Initialize maps for unstarted runtime. This needs to be here, as running clinits needs this
    164   // set up.
    165   if (!unstarted_initialized_) {
    166     interpreter::UnstartedRuntime::Initialize();
    167     unstarted_initialized_ = true;
    168   }
    169 
    170   {
    171     ScopedObjectAccess soa(Thread::Current());
    172     runtime_->RunRootClinits(soa.Self());
    173   }
    174 
    175   // We're back in native, take the opportunity to initialize well known classes.
    176   WellKnownClasses::Init(Thread::Current()->GetJniEnv());
    177 
    178   // Create the heap thread pool so that the GC runs in parallel for tests. Normally, the thread
    179   // pool is created by the runtime.
    180   runtime_->GetHeap()->CreateThreadPool();
    181   runtime_->GetHeap()->VerifyHeap();  // Check for heap corruption before the test
    182   // Reduce timinig-dependent flakiness in OOME behavior (eg StubTest.AllocObject).
    183   runtime_->GetHeap()->SetMinIntervalHomogeneousSpaceCompactionByOom(0U);
    184 }
    185 
    186 void CommonRuntimeTestImpl::TearDown() {
    187   CommonArtTestImpl::TearDown();
    188   if (runtime_ != nullptr) {
    189     runtime_->GetHeap()->VerifyHeap();  // Check for heap corruption after the test
    190   }
    191 }
    192 
    193 // Check that for target builds we have ART_TARGET_NATIVETEST_DIR set.
    194 #ifdef ART_TARGET
    195 #ifndef ART_TARGET_NATIVETEST_DIR
    196 #error "ART_TARGET_NATIVETEST_DIR not set."
    197 #endif
    198 // Wrap it as a string literal.
    199 #define ART_TARGET_NATIVETEST_DIR_STRING STRINGIFY(ART_TARGET_NATIVETEST_DIR) "/"
    200 #else
    201 #define ART_TARGET_NATIVETEST_DIR_STRING ""
    202 #endif
    203 
    204 std::vector<const DexFile*> CommonRuntimeTestImpl::GetDexFiles(jobject jclass_loader) {
    205   ScopedObjectAccess soa(Thread::Current());
    206 
    207   StackHandleScope<1> hs(soa.Self());
    208   Handle<mirror::ClassLoader> class_loader = hs.NewHandle(
    209       soa.Decode<mirror::ClassLoader>(jclass_loader));
    210   return GetDexFiles(soa, class_loader);
    211 }
    212 
    213 std::vector<const DexFile*> CommonRuntimeTestImpl::GetDexFiles(
    214     ScopedObjectAccess& soa,
    215     Handle<mirror::ClassLoader> class_loader) {
    216   DCHECK(
    217       (class_loader->GetClass() ==
    218           soa.Decode<mirror::Class>(WellKnownClasses::dalvik_system_PathClassLoader)) ||
    219       (class_loader->GetClass() ==
    220           soa.Decode<mirror::Class>(WellKnownClasses::dalvik_system_DelegateLastClassLoader)));
    221 
    222   std::vector<const DexFile*> ret;
    223   VisitClassLoaderDexFiles(soa,
    224                            class_loader,
    225                            [&](const DexFile* cp_dex_file) {
    226                              if (cp_dex_file == nullptr) {
    227                                LOG(WARNING) << "Null DexFile";
    228                              } else {
    229                                ret.push_back(cp_dex_file);
    230                              }
    231                              return true;
    232                            });
    233   return ret;
    234 }
    235 
    236 const DexFile* CommonRuntimeTestImpl::GetFirstDexFile(jobject jclass_loader) {
    237   std::vector<const DexFile*> tmp(GetDexFiles(jclass_loader));
    238   DCHECK(!tmp.empty());
    239   const DexFile* ret = tmp[0];
    240   DCHECK(ret != nullptr);
    241   return ret;
    242 }
    243 
    244 jobject CommonRuntimeTestImpl::LoadMultiDex(const char* first_dex_name,
    245                                             const char* second_dex_name) {
    246   std::vector<std::unique_ptr<const DexFile>> first_dex_files = OpenTestDexFiles(first_dex_name);
    247   std::vector<std::unique_ptr<const DexFile>> second_dex_files = OpenTestDexFiles(second_dex_name);
    248   std::vector<const DexFile*> class_path;
    249   CHECK_NE(0U, first_dex_files.size());
    250   CHECK_NE(0U, second_dex_files.size());
    251   for (auto& dex_file : first_dex_files) {
    252     class_path.push_back(dex_file.get());
    253     loaded_dex_files_.push_back(std::move(dex_file));
    254   }
    255   for (auto& dex_file : second_dex_files) {
    256     class_path.push_back(dex_file.get());
    257     loaded_dex_files_.push_back(std::move(dex_file));
    258   }
    259 
    260   Thread* self = Thread::Current();
    261   jobject class_loader = Runtime::Current()->GetClassLinker()->CreatePathClassLoader(self,
    262                                                                                      class_path);
    263   self->SetClassLoaderOverride(class_loader);
    264   return class_loader;
    265 }
    266 
    267 jobject CommonRuntimeTestImpl::LoadDex(const char* dex_name) {
    268   jobject class_loader = LoadDexInPathClassLoader(dex_name, nullptr);
    269   Thread::Current()->SetClassLoaderOverride(class_loader);
    270   return class_loader;
    271 }
    272 
    273 jobject CommonRuntimeTestImpl::LoadDexInWellKnownClassLoader(const std::string& dex_name,
    274                                                              jclass loader_class,
    275                                                              jobject parent_loader,
    276                                                              jobject shared_libraries) {
    277   std::vector<std::unique_ptr<const DexFile>> dex_files = OpenTestDexFiles(dex_name.c_str());
    278   std::vector<const DexFile*> class_path;
    279   CHECK_NE(0U, dex_files.size());
    280   for (auto& dex_file : dex_files) {
    281     class_path.push_back(dex_file.get());
    282     loaded_dex_files_.push_back(std::move(dex_file));
    283   }
    284   Thread* self = Thread::Current();
    285   ScopedObjectAccess soa(self);
    286 
    287   jobject result = Runtime::Current()->GetClassLinker()->CreateWellKnownClassLoader(
    288       self,
    289       class_path,
    290       loader_class,
    291       parent_loader,
    292       shared_libraries);
    293 
    294   {
    295     // Verify we build the correct chain.
    296 
    297     ObjPtr<mirror::ClassLoader> actual_class_loader = soa.Decode<mirror::ClassLoader>(result);
    298     // Verify that the result has the correct class.
    299     CHECK_EQ(soa.Decode<mirror::Class>(loader_class), actual_class_loader->GetClass());
    300     // Verify that the parent is not null. The boot class loader will be set up as a
    301     // proper object.
    302     ObjPtr<mirror::ClassLoader> actual_parent(actual_class_loader->GetParent());
    303     CHECK(actual_parent != nullptr);
    304 
    305     if (parent_loader != nullptr) {
    306       // We were given a parent. Verify that it's what we expect.
    307       ObjPtr<mirror::ClassLoader> expected_parent = soa.Decode<mirror::ClassLoader>(parent_loader);
    308       CHECK_EQ(expected_parent, actual_parent);
    309     } else {
    310       // No parent given. The parent must be the BootClassLoader.
    311       CHECK(Runtime::Current()->GetClassLinker()->IsBootClassLoader(soa, actual_parent));
    312     }
    313   }
    314 
    315   return result;
    316 }
    317 
    318 jobject CommonRuntimeTestImpl::LoadDexInPathClassLoader(const std::string& dex_name,
    319                                                         jobject parent_loader,
    320                                                         jobject shared_libraries) {
    321   return LoadDexInWellKnownClassLoader(dex_name,
    322                                        WellKnownClasses::dalvik_system_PathClassLoader,
    323                                        parent_loader,
    324                                        shared_libraries);
    325 }
    326 
    327 jobject CommonRuntimeTestImpl::LoadDexInDelegateLastClassLoader(const std::string& dex_name,
    328                                                                 jobject parent_loader) {
    329   return LoadDexInWellKnownClassLoader(dex_name,
    330                                        WellKnownClasses::dalvik_system_DelegateLastClassLoader,
    331                                        parent_loader);
    332 }
    333 
    334 jobject CommonRuntimeTestImpl::LoadDexInInMemoryDexClassLoader(const std::string& dex_name,
    335                                                                jobject parent_loader) {
    336   return LoadDexInWellKnownClassLoader(dex_name,
    337                                        WellKnownClasses::dalvik_system_InMemoryDexClassLoader,
    338                                        parent_loader);
    339 }
    340 
    341 void CommonRuntimeTestImpl::FillHeap(Thread* self,
    342                                      ClassLinker* class_linker,
    343                                      VariableSizedHandleScope* handle_scope) {
    344   DCHECK(handle_scope != nullptr);
    345 
    346   Runtime::Current()->GetHeap()->SetIdealFootprint(1 * GB);
    347 
    348   // Class java.lang.Object.
    349   Handle<mirror::Class> c(handle_scope->NewHandle(
    350       class_linker->FindSystemClass(self, "Ljava/lang/Object;")));
    351   // Array helps to fill memory faster.
    352   Handle<mirror::Class> ca(handle_scope->NewHandle(
    353       class_linker->FindSystemClass(self, "[Ljava/lang/Object;")));
    354 
    355   // Start allocating with ~128K
    356   size_t length = 128 * KB;
    357   while (length > 40) {
    358     const int32_t array_length = length / 4;  // Object[] has elements of size 4.
    359     MutableHandle<mirror::Object> h(handle_scope->NewHandle<mirror::Object>(
    360         mirror::ObjectArray<mirror::Object>::Alloc(self, ca.Get(), array_length)));
    361     if (self->IsExceptionPending() || h == nullptr) {
    362       self->ClearException();
    363 
    364       // Try a smaller length
    365       length = length / 2;
    366       // Use at most a quarter the reported free space.
    367       size_t mem = Runtime::Current()->GetHeap()->GetFreeMemory();
    368       if (length * 4 > mem) {
    369         length = mem / 4;
    370       }
    371     }
    372   }
    373 
    374   // Allocate simple objects till it fails.
    375   while (!self->IsExceptionPending()) {
    376     handle_scope->NewHandle<mirror::Object>(c->AllocObject(self));
    377   }
    378   self->ClearException();
    379 }
    380 
    381 void CommonRuntimeTestImpl::SetUpRuntimeOptionsForFillHeap(RuntimeOptions *options) {
    382   // Use a smaller heap
    383   bool found = false;
    384   for (std::pair<std::string, const void*>& pair : *options) {
    385     if (pair.first.find("-Xmx") == 0) {
    386       pair.first = "-Xmx4M";  // Smallest we can go.
    387       found = true;
    388     }
    389   }
    390   if (!found) {
    391     options->emplace_back("-Xmx4M", nullptr);
    392   }
    393 }
    394 
    395 void CommonRuntimeTestImpl::MakeInterpreted(ObjPtr<mirror::Class> klass) {
    396   PointerSize pointer_size = class_linker_->GetImagePointerSize();
    397   for (ArtMethod& method : klass->GetMethods(pointer_size)) {
    398     class_linker_->SetEntryPointsToInterpreter(&method);
    399   }
    400 }
    401 
    402 bool CommonRuntimeTestImpl::StartDex2OatCommandLine(/*out*/std::vector<std::string>* argv,
    403                                                     /*out*/std::string* error_msg) {
    404   DCHECK(argv != nullptr);
    405   DCHECK(argv->empty());
    406 
    407   Runtime* runtime = Runtime::Current();
    408   const std::vector<gc::space::ImageSpace*>& image_spaces =
    409       runtime->GetHeap()->GetBootImageSpaces();
    410   if (image_spaces.empty()) {
    411     *error_msg = "No image location found for Dex2Oat.";
    412     return false;
    413   }
    414   std::string image_location = image_spaces[0]->GetImageLocation();
    415 
    416   argv->push_back(runtime->GetCompilerExecutable());
    417   if (runtime->IsJavaDebuggable()) {
    418     argv->push_back("--debuggable");
    419   }
    420   runtime->AddCurrentRuntimeFeaturesAsDex2OatArguments(argv);
    421 
    422   argv->push_back("--runtime-arg");
    423   argv->push_back(GetClassPathOption("-Xbootclasspath:", GetLibCoreDexFileNames()));
    424   argv->push_back("--runtime-arg");
    425   argv->push_back(GetClassPathOption("-Xbootclasspath-locations:", GetLibCoreDexLocations()));
    426 
    427   argv->push_back("--boot-image=" + image_location);
    428 
    429   std::vector<std::string> compiler_options = runtime->GetCompilerOptions();
    430   argv->insert(argv->end(), compiler_options.begin(), compiler_options.end());
    431   return true;
    432 }
    433 
    434 CheckJniAbortCatcher::CheckJniAbortCatcher() : vm_(Runtime::Current()->GetJavaVM()) {
    435   vm_->SetCheckJniAbortHook(Hook, &actual_);
    436 }
    437 
    438 CheckJniAbortCatcher::~CheckJniAbortCatcher() {
    439   vm_->SetCheckJniAbortHook(nullptr, nullptr);
    440   EXPECT_TRUE(actual_.empty()) << actual_;
    441 }
    442 
    443 void CheckJniAbortCatcher::Check(const std::string& expected_text) {
    444   Check(expected_text.c_str());
    445 }
    446 
    447 void CheckJniAbortCatcher::Check(const char* expected_text) {
    448   EXPECT_TRUE(actual_.find(expected_text) != std::string::npos) << "\n"
    449       << "Expected to find: " << expected_text << "\n"
    450       << "In the output   : " << actual_;
    451   actual_.clear();
    452 }
    453 
    454 void CheckJniAbortCatcher::Hook(void* data, const std::string& reason) {
    455   // We use += because when we're hooking the aborts like this, multiple problems can be found.
    456   *reinterpret_cast<std::string*>(data) += reason;
    457 }
    458 
    459 }  // namespace art
    460 
    461 // Allow other test code to run global initialization/configuration before
    462 // gtest infra takes over.
    463 extern "C"
    464 __attribute__((visibility("default"))) __attribute__((weak))
    465 void ArtTestGlobalInit() {
    466   LOG(ERROR) << "ArtTestGlobalInit in common_runtime_test";
    467 }
    468 
    469 int main(int argc, char **argv) {
    470   // Gtests can be very noisy. For example, an executable with multiple tests will trigger native
    471   // bridge warnings. The following line reduces the minimum log severity to ERROR and suppresses
    472   // everything else. In case you want to see all messages, comment out the line.
    473   setenv("ANDROID_LOG_TAGS", "*:e", 1);
    474 
    475   art::Locks::Init();
    476   art::InitLogging(argv, art::Runtime::Abort);
    477   art::MemMap::Init();
    478   LOG(INFO) << "Running main() from common_runtime_test.cc...";
    479   testing::InitGoogleTest(&argc, argv);
    480   ArtTestGlobalInit();
    481   return RUN_ALL_TESTS();
    482 }
    483