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