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