• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2019 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 <thread>
20 
21 #include "android-base/logging.h"
22 #include "base/locks.h"
23 #include "base/mutex.h"
24 #include "oat/elf_file.h"
25 #include "runtime.h"
26 #include "thread-current-inl.h"
27 
28 #ifdef ART_TARGET_ANDROID
29 #include "android-base/properties.h"
30 #endif
31 
32 namespace art HIDDEN {
33 
34 class RuntimeTest : public CommonRuntimeTest {};
35 
36 // Ensure that abort works with ThreadList locks held.
37 
TEST_F(RuntimeTest,AbortWithThreadListLockHeld)38 TEST_F(RuntimeTest, AbortWithThreadListLockHeld) {
39   // This assumes the test is run single-threaded: do not start the runtime to avoid daemon threads.
40 
41   constexpr const char* kDeathRegex = "Skipping all-threads dump as locks are held";
42   ASSERT_DEATH({
43     // The regex only works if we can ensure output goes to stderr.
44     android::base::SetLogger(android::base::StderrLogger);
45 
46     MutexLock mu(Thread::Current(), *Locks::thread_list_lock_);
47     Runtime::Abort("Attempt to abort");
48   }, kDeathRegex);
49 }
50 
51 
TEST_F(RuntimeTest,AbortWithThreadSuspendCountLockHeld)52 TEST_F(RuntimeTest, AbortWithThreadSuspendCountLockHeld) {
53   // This assumes the test is run single-threaded: do not start the runtime to avoid daemon threads.
54 
55   constexpr const char* kDeathRegex = "Skipping all-threads dump as locks are held";
56   ASSERT_DEATH({
57     // The regex only works if we can ensure output goes to stderr.
58     android::base::SetLogger(android::base::StderrLogger);
59 
60     MutexLock mu(Thread::Current(), *Locks::thread_suspend_count_lock_);
61     Runtime::Abort("Attempt to abort");
62   }, kDeathRegex);
63 }
64 
TEST_F(RuntimeTest,AbortFromUnattachedThread)65 TEST_F(RuntimeTest, AbortFromUnattachedThread) {
66   // This assumes the test is run single-threaded: do not start the runtime to avoid daemon threads.
67 
68   constexpr const char* kDeathRegex = "Going down";
69   ASSERT_EXIT({
70     // The regex only works if we can ensure output goes to stderr.
71     android::base::SetLogger(android::base::StderrLogger);
72 
73     Thread::Current()->TransitionFromSuspendedToRunnable();
74     runtime_->Start();
75 
76     std::thread t([]() {
77       LOG(FATAL) << "Going down";
78     });
79     t.join();
80   }, ::testing::KilledBySignal(SIGABRT), kDeathRegex);
81 }
82 
83 // It is possible to run tests that validate an existing deployed on-device ART APEX ('standalone'
84 // tests). If these tests expect to load ELF files with a particular alignment, but those ELF files
85 // were created with a different alignment, there will be many difficult-to-debug failures. This
86 // test aims to identify this mismatch, related to whether or not the runtimes were built to be
87 // page-size agnostic.
TEST_F(RuntimeTest,ElfAlignmentMismatch)88 TEST_F(RuntimeTest, ElfAlignmentMismatch) {
89 #ifdef ART_TARGET_ANDROID
90   bool platform_pga = android::base::GetBoolProperty("ro.product.build.no_bionic_page_size_macro",
91                                                      false);
92   if (kPageSizeAgnostic != platform_pga) {
93     LOG(WARNING) << "Test configured with kPageSizeAgnostic=" << kPageSizeAgnostic << ", but "
94                  << "platform ro.product.build.no_bionic_page_size_macro=" << platform_pga << ".";
95   }
96 #endif
97   // Determine the alignment of the ART APEX by reading the alignment of boot.oat.
98   std::string core_oat_location = GetSystemImageFilename(GetCoreOatLocation().c_str(), kRuntimeISA);
99   std::unique_ptr<File> core_oat_file(OS::OpenFileForReading(core_oat_location.c_str()));
100   ASSERT_TRUE(core_oat_file.get() != nullptr) << core_oat_location;
101 
102   std::string error_msg;
103   std::unique_ptr<ElfFile> elf_file(ElfFile::Open(core_oat_file.get(),
104                                                   /*writable=*/false,
105                                                   /*program_header_only=*/true,
106                                                   /*low_4gb=*/false,
107                                                   &error_msg));
108   ASSERT_TRUE(elf_file != nullptr) << error_msg;
109   EXPECT_EQ(kElfSegmentAlignment, elf_file->GetElfSegmentAlignmentFromFile());
110 }
111 
112 }  // namespace art
113