Home | History | Annotate | Download | only in runtime
      1 /*
      2  * Copyright (C) 2017 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 "runtime_callbacks.h"
     18 
     19 #include <signal.h>
     20 #include <sys/types.h>
     21 #include <unistd.h>
     22 
     23 #include <initializer_list>
     24 #include <memory>
     25 #include <mutex>
     26 #include <string>
     27 
     28 #include "jni.h"
     29 
     30 #include "art_method-inl.h"
     31 #include "base/mutex.h"
     32 #include "class_linker.h"
     33 #include "common_runtime_test.h"
     34 #include "dex/class_reference.h"
     35 #include "handle.h"
     36 #include "handle_scope-inl.h"
     37 #include "mem_map.h"
     38 #include "mirror/class-inl.h"
     39 #include "mirror/class_loader.h"
     40 #include "monitor.h"
     41 #include "nativehelper/scoped_local_ref.h"
     42 #include "obj_ptr.h"
     43 #include "runtime.h"
     44 #include "scoped_thread_state_change-inl.h"
     45 #include "thread-inl.h"
     46 #include "thread_list.h"
     47 #include "well_known_classes.h"
     48 
     49 namespace art {
     50 
     51 class RuntimeCallbacksTest : public CommonRuntimeTest {
     52  protected:
     53   void SetUp() OVERRIDE {
     54     CommonRuntimeTest::SetUp();
     55 
     56     Thread* self = Thread::Current();
     57     ScopedObjectAccess soa(self);
     58     ScopedThreadSuspension sts(self, kWaitingForDebuggerToAttach);
     59     ScopedSuspendAll ssa("RuntimeCallbacksTest SetUp");
     60     AddListener();
     61   }
     62 
     63   void TearDown() OVERRIDE {
     64     {
     65       Thread* self = Thread::Current();
     66       ScopedObjectAccess soa(self);
     67       ScopedThreadSuspension sts(self, kWaitingForDebuggerToAttach);
     68       ScopedSuspendAll ssa("RuntimeCallbacksTest TearDown");
     69       RemoveListener();
     70     }
     71 
     72     CommonRuntimeTest::TearDown();
     73   }
     74 
     75   virtual void AddListener() REQUIRES(Locks::mutator_lock_) = 0;
     76   virtual void RemoveListener() REQUIRES(Locks::mutator_lock_) = 0;
     77 
     78   void MakeExecutable(ObjPtr<mirror::Class> klass) REQUIRES_SHARED(Locks::mutator_lock_) {
     79     CHECK(klass != nullptr);
     80     PointerSize pointer_size = class_linker_->GetImagePointerSize();
     81     for (auto& m : klass->GetMethods(pointer_size)) {
     82       if (!m.IsAbstract()) {
     83         class_linker_->SetEntryPointsToInterpreter(&m);
     84       }
     85     }
     86   }
     87 };
     88 
     89 class ThreadLifecycleCallbackRuntimeCallbacksTest : public RuntimeCallbacksTest {
     90  public:
     91   static void* PthreadsCallback(void* arg ATTRIBUTE_UNUSED) {
     92     // Attach.
     93     Runtime* runtime = Runtime::Current();
     94     CHECK(runtime->AttachCurrentThread("ThreadLifecycle test thread", true, nullptr, false));
     95 
     96     // Detach.
     97     runtime->DetachCurrentThread();
     98 
     99     // Die...
    100     return nullptr;
    101   }
    102 
    103  protected:
    104   void AddListener() OVERRIDE REQUIRES(Locks::mutator_lock_) {
    105     Runtime::Current()->GetRuntimeCallbacks()->AddThreadLifecycleCallback(&cb_);
    106   }
    107   void RemoveListener() OVERRIDE REQUIRES(Locks::mutator_lock_) {
    108     Runtime::Current()->GetRuntimeCallbacks()->RemoveThreadLifecycleCallback(&cb_);
    109   }
    110 
    111   enum CallbackState {
    112     kBase,
    113     kStarted,
    114     kDied,
    115     kWrongStart,
    116     kWrongDeath,
    117   };
    118 
    119   struct Callback : public ThreadLifecycleCallback {
    120     void ThreadStart(Thread* self) OVERRIDE {
    121       if (state == CallbackState::kBase) {
    122         state = CallbackState::kStarted;
    123         stored_self = self;
    124       } else {
    125         state = CallbackState::kWrongStart;
    126       }
    127     }
    128 
    129     void ThreadDeath(Thread* self) OVERRIDE {
    130       if (state == CallbackState::kStarted && self == stored_self) {
    131         state = CallbackState::kDied;
    132       } else {
    133         state = CallbackState::kWrongDeath;
    134       }
    135     }
    136 
    137     Thread* stored_self;
    138     CallbackState state = CallbackState::kBase;
    139   };
    140 
    141   Callback cb_;
    142 };
    143 
    144 TEST_F(ThreadLifecycleCallbackRuntimeCallbacksTest, ThreadLifecycleCallbackJava) {
    145   Thread* self = Thread::Current();
    146 
    147   self->TransitionFromSuspendedToRunnable();
    148   bool started = runtime_->Start();
    149   ASSERT_TRUE(started);
    150 
    151   cb_.state = CallbackState::kBase;  // Ignore main thread attach.
    152 
    153   {
    154     ScopedObjectAccess soa(self);
    155     MakeExecutable(soa.Decode<mirror::Class>(WellKnownClasses::java_lang_Thread));
    156   }
    157 
    158   JNIEnv* env = self->GetJniEnv();
    159 
    160   ScopedLocalRef<jobject> thread_name(env,
    161                                       env->NewStringUTF("ThreadLifecycleCallback test thread"));
    162   ASSERT_TRUE(thread_name.get() != nullptr);
    163 
    164   ScopedLocalRef<jobject> thread(env, env->AllocObject(WellKnownClasses::java_lang_Thread));
    165   ASSERT_TRUE(thread.get() != nullptr);
    166 
    167   env->CallNonvirtualVoidMethod(thread.get(),
    168                                 WellKnownClasses::java_lang_Thread,
    169                                 WellKnownClasses::java_lang_Thread_init,
    170                                 runtime_->GetMainThreadGroup(),
    171                                 thread_name.get(),
    172                                 kMinThreadPriority,
    173                                 JNI_FALSE);
    174   ASSERT_FALSE(env->ExceptionCheck());
    175 
    176   jmethodID start_id = env->GetMethodID(WellKnownClasses::java_lang_Thread, "start", "()V");
    177   ASSERT_TRUE(start_id != nullptr);
    178 
    179   env->CallVoidMethod(thread.get(), start_id);
    180   ASSERT_FALSE(env->ExceptionCheck());
    181 
    182   jmethodID join_id = env->GetMethodID(WellKnownClasses::java_lang_Thread, "join", "()V");
    183   ASSERT_TRUE(join_id != nullptr);
    184 
    185   env->CallVoidMethod(thread.get(), join_id);
    186   ASSERT_FALSE(env->ExceptionCheck());
    187 
    188   EXPECT_TRUE(cb_.state == CallbackState::kDied) << static_cast<int>(cb_.state);
    189 }
    190 
    191 TEST_F(ThreadLifecycleCallbackRuntimeCallbacksTest, ThreadLifecycleCallbackAttach) {
    192   std::string error_msg;
    193   std::unique_ptr<MemMap> stack(MemMap::MapAnonymous("ThreadLifecycleCallback Thread",
    194                                                      nullptr,
    195                                                      128 * kPageSize,  // Just some small stack.
    196                                                      PROT_READ | PROT_WRITE,
    197                                                      false,
    198                                                      false,
    199                                                      &error_msg));
    200   ASSERT_FALSE(stack == nullptr) << error_msg;
    201 
    202   const char* reason = "ThreadLifecycleCallback test thread";
    203   pthread_attr_t attr;
    204   CHECK_PTHREAD_CALL(pthread_attr_init, (&attr), reason);
    205   CHECK_PTHREAD_CALL(pthread_attr_setstack, (&attr, stack->Begin(), stack->Size()), reason);
    206   pthread_t pthread;
    207   CHECK_PTHREAD_CALL(pthread_create,
    208                      (&pthread,
    209                          &attr,
    210                          &ThreadLifecycleCallbackRuntimeCallbacksTest::PthreadsCallback,
    211                          this),
    212                          reason);
    213   CHECK_PTHREAD_CALL(pthread_attr_destroy, (&attr), reason);
    214 
    215   CHECK_PTHREAD_CALL(pthread_join, (pthread, nullptr), "ThreadLifecycleCallback test shutdown");
    216 
    217   // Detach is not a ThreadDeath event, so we expect to be in state Started.
    218   EXPECT_TRUE(cb_.state == CallbackState::kStarted) << static_cast<int>(cb_.state);
    219 }
    220 
    221 class ClassLoadCallbackRuntimeCallbacksTest : public RuntimeCallbacksTest {
    222  protected:
    223   void AddListener() OVERRIDE REQUIRES(Locks::mutator_lock_) {
    224     Runtime::Current()->GetRuntimeCallbacks()->AddClassLoadCallback(&cb_);
    225   }
    226   void RemoveListener() OVERRIDE REQUIRES(Locks::mutator_lock_) {
    227     Runtime::Current()->GetRuntimeCallbacks()->RemoveClassLoadCallback(&cb_);
    228   }
    229 
    230   bool Expect(std::initializer_list<const char*> list) {
    231     if (cb_.data.size() != list.size()) {
    232       PrintError(list);
    233       return false;
    234     }
    235 
    236     if (!std::equal(cb_.data.begin(), cb_.data.end(), list.begin())) {
    237       PrintError(list);
    238       return false;
    239     }
    240 
    241     return true;
    242   }
    243 
    244   void PrintError(std::initializer_list<const char*> list) {
    245     LOG(ERROR) << "Expected:";
    246     for (const char* expected : list) {
    247       LOG(ERROR) << "  " << expected;
    248     }
    249     LOG(ERROR) << "Found:";
    250     for (const auto& s : cb_.data) {
    251       LOG(ERROR) << "  " << s;
    252     }
    253   }
    254 
    255   struct Callback : public ClassLoadCallback {
    256     virtual void ClassPreDefine(const char* descriptor,
    257                                 Handle<mirror::Class> klass ATTRIBUTE_UNUSED,
    258                                 Handle<mirror::ClassLoader> class_loader ATTRIBUTE_UNUSED,
    259                                 const DexFile& initial_dex_file,
    260                                 const DexFile::ClassDef& initial_class_def ATTRIBUTE_UNUSED,
    261                                 /*out*/DexFile const** final_dex_file ATTRIBUTE_UNUSED,
    262                                 /*out*/DexFile::ClassDef const** final_class_def ATTRIBUTE_UNUSED)
    263         OVERRIDE REQUIRES_SHARED(Locks::mutator_lock_) {
    264       const std::string& location = initial_dex_file.GetLocation();
    265       std::string event =
    266           std::string("PreDefine:") + descriptor + " <" +
    267           location.substr(location.rfind('/') + 1, location.size()) + ">";
    268       data.push_back(event);
    269     }
    270 
    271     void ClassLoad(Handle<mirror::Class> klass) OVERRIDE REQUIRES_SHARED(Locks::mutator_lock_) {
    272       std::string tmp;
    273       std::string event = std::string("Load:") + klass->GetDescriptor(&tmp);
    274       data.push_back(event);
    275     }
    276 
    277     void ClassPrepare(Handle<mirror::Class> temp_klass,
    278                       Handle<mirror::Class> klass) OVERRIDE REQUIRES_SHARED(Locks::mutator_lock_) {
    279       std::string tmp, tmp2;
    280       std::string event = std::string("Prepare:") + klass->GetDescriptor(&tmp)
    281           + "[" + temp_klass->GetDescriptor(&tmp2) + "]";
    282       data.push_back(event);
    283     }
    284 
    285     std::vector<std::string> data;
    286   };
    287 
    288   Callback cb_;
    289 };
    290 
    291 TEST_F(ClassLoadCallbackRuntimeCallbacksTest, ClassLoadCallback) {
    292   ScopedObjectAccess soa(Thread::Current());
    293   jobject jclass_loader = LoadDex("XandY");
    294   VariableSizedHandleScope hs(soa.Self());
    295   Handle<mirror::ClassLoader> class_loader(hs.NewHandle(
    296       soa.Decode<mirror::ClassLoader>(jclass_loader)));
    297 
    298   const char* descriptor_y = "LY;";
    299   Handle<mirror::Class> h_Y(
    300       hs.NewHandle(class_linker_->FindClass(soa.Self(), descriptor_y, class_loader)));
    301   ASSERT_TRUE(h_Y != nullptr);
    302 
    303   bool expect1 = Expect({ "PreDefine:LY; <art-gtest-XandY.jar>",
    304                           "PreDefine:LX; <art-gtest-XandY.jar>",
    305                           "Load:LX;",
    306                           "Prepare:LX;[LX;]",
    307                           "Load:LY;",
    308                           "Prepare:LY;[LY;]" });
    309   EXPECT_TRUE(expect1);
    310 
    311   cb_.data.clear();
    312 
    313   ASSERT_TRUE(class_linker_->EnsureInitialized(Thread::Current(), h_Y, true, true));
    314 
    315   bool expect2 = Expect({ "PreDefine:LY$Z; <art-gtest-XandY.jar>",
    316                           "Load:LY$Z;",
    317                           "Prepare:LY$Z;[LY$Z;]" });
    318   EXPECT_TRUE(expect2);
    319 }
    320 
    321 class RuntimeSigQuitCallbackRuntimeCallbacksTest : public RuntimeCallbacksTest {
    322  protected:
    323   void AddListener() OVERRIDE REQUIRES(Locks::mutator_lock_) {
    324     Runtime::Current()->GetRuntimeCallbacks()->AddRuntimeSigQuitCallback(&cb_);
    325   }
    326   void RemoveListener() OVERRIDE REQUIRES(Locks::mutator_lock_) {
    327     Runtime::Current()->GetRuntimeCallbacks()->RemoveRuntimeSigQuitCallback(&cb_);
    328   }
    329 
    330   struct Callback : public RuntimeSigQuitCallback {
    331     void SigQuit() OVERRIDE {
    332       ++sigquit_count;
    333     }
    334 
    335     size_t sigquit_count = 0;
    336   };
    337 
    338   Callback cb_;
    339 };
    340 
    341 TEST_F(RuntimeSigQuitCallbackRuntimeCallbacksTest, SigQuit) {
    342   // SigQuit induces a dump. ASAN isn't happy with libunwind reading memory.
    343   TEST_DISABLED_FOR_MEMORY_TOOL_ASAN();
    344 
    345   // The runtime needs to be started for the signal handler.
    346   Thread* self = Thread::Current();
    347 
    348   self->TransitionFromSuspendedToRunnable();
    349   bool started = runtime_->Start();
    350   ASSERT_TRUE(started);
    351 
    352   EXPECT_EQ(0u, cb_.sigquit_count);
    353 
    354   kill(getpid(), SIGQUIT);
    355 
    356   // Try a few times.
    357   for (size_t i = 0; i != 30; ++i) {
    358     if (cb_.sigquit_count == 0) {
    359       sleep(1);
    360     } else {
    361       break;
    362     }
    363   }
    364   EXPECT_EQ(1u, cb_.sigquit_count);
    365 }
    366 
    367 class RuntimePhaseCallbackRuntimeCallbacksTest : public RuntimeCallbacksTest {
    368  protected:
    369   void AddListener() OVERRIDE REQUIRES(Locks::mutator_lock_) {
    370     Runtime::Current()->GetRuntimeCallbacks()->AddRuntimePhaseCallback(&cb_);
    371   }
    372   void RemoveListener() OVERRIDE REQUIRES(Locks::mutator_lock_) {
    373     Runtime::Current()->GetRuntimeCallbacks()->RemoveRuntimePhaseCallback(&cb_);
    374   }
    375 
    376   void TearDown() OVERRIDE {
    377     // Bypass RuntimeCallbacksTest::TearDown, as the runtime is already gone.
    378     CommonRuntimeTest::TearDown();
    379   }
    380 
    381   struct Callback : public RuntimePhaseCallback {
    382     void NextRuntimePhase(RuntimePhaseCallback::RuntimePhase p) OVERRIDE {
    383       if (p == RuntimePhaseCallback::RuntimePhase::kInitialAgents) {
    384         if (start_seen > 0 || init_seen > 0 || death_seen > 0) {
    385           LOG(FATAL) << "Unexpected order";
    386         }
    387         ++initial_agents_seen;
    388       } else if (p == RuntimePhaseCallback::RuntimePhase::kStart) {
    389         if (init_seen > 0 || death_seen > 0) {
    390           LOG(FATAL) << "Init seen before start.";
    391         }
    392         ++start_seen;
    393       } else if (p == RuntimePhaseCallback::RuntimePhase::kInit) {
    394         ++init_seen;
    395       } else if (p == RuntimePhaseCallback::RuntimePhase::kDeath) {
    396         ++death_seen;
    397       } else {
    398         LOG(FATAL) << "Unknown phase " << static_cast<uint32_t>(p);
    399       }
    400     }
    401 
    402     size_t initial_agents_seen = 0;
    403     size_t start_seen = 0;
    404     size_t init_seen = 0;
    405     size_t death_seen = 0;
    406   };
    407 
    408   Callback cb_;
    409 };
    410 
    411 TEST_F(RuntimePhaseCallbackRuntimeCallbacksTest, Phases) {
    412   ASSERT_EQ(0u, cb_.initial_agents_seen);
    413   ASSERT_EQ(0u, cb_.start_seen);
    414   ASSERT_EQ(0u, cb_.init_seen);
    415   ASSERT_EQ(0u, cb_.death_seen);
    416 
    417   // Start the runtime.
    418   {
    419     Thread* self = Thread::Current();
    420     self->TransitionFromSuspendedToRunnable();
    421     bool started = runtime_->Start();
    422     ASSERT_TRUE(started);
    423   }
    424 
    425   ASSERT_EQ(0u, cb_.initial_agents_seen);
    426   ASSERT_EQ(1u, cb_.start_seen);
    427   ASSERT_EQ(1u, cb_.init_seen);
    428   ASSERT_EQ(0u, cb_.death_seen);
    429 
    430   // Delete the runtime.
    431   runtime_.reset();
    432 
    433   ASSERT_EQ(0u, cb_.initial_agents_seen);
    434   ASSERT_EQ(1u, cb_.start_seen);
    435   ASSERT_EQ(1u, cb_.init_seen);
    436   ASSERT_EQ(1u, cb_.death_seen);
    437 }
    438 
    439 class MonitorWaitCallbacksTest : public RuntimeCallbacksTest {
    440  protected:
    441   void AddListener() OVERRIDE REQUIRES(Locks::mutator_lock_) {
    442     Runtime::Current()->GetRuntimeCallbacks()->AddMonitorCallback(&cb_);
    443   }
    444   void RemoveListener() OVERRIDE REQUIRES(Locks::mutator_lock_) {
    445     Runtime::Current()->GetRuntimeCallbacks()->RemoveMonitorCallback(&cb_);
    446   }
    447 
    448   struct Callback : public MonitorCallback {
    449     bool IsInterestingObject(mirror::Object* obj) REQUIRES_SHARED(art::Locks::mutator_lock_) {
    450       if (!obj->IsClass()) {
    451         return false;
    452       }
    453       std::lock_guard<std::mutex> lock(ref_guard_);
    454       mirror::Class* k = obj->AsClass();
    455       ClassReference test = { &k->GetDexFile(), k->GetDexClassDefIndex() };
    456       return ref_ == test;
    457     }
    458 
    459     void SetInterestingObject(mirror::Object* obj) REQUIRES_SHARED(art::Locks::mutator_lock_) {
    460       std::lock_guard<std::mutex> lock(ref_guard_);
    461       mirror::Class* k = obj->AsClass();
    462       ref_ = { &k->GetDexFile(), k->GetDexClassDefIndex() };
    463     }
    464 
    465     void MonitorContendedLocking(Monitor* mon ATTRIBUTE_UNUSED)
    466         REQUIRES_SHARED(Locks::mutator_lock_) { }
    467 
    468     void MonitorContendedLocked(Monitor* mon ATTRIBUTE_UNUSED)
    469         REQUIRES_SHARED(Locks::mutator_lock_) { }
    470 
    471     void ObjectWaitStart(Handle<mirror::Object> obj, int64_t millis ATTRIBUTE_UNUSED)
    472         REQUIRES_SHARED(Locks::mutator_lock_) {
    473       if (IsInterestingObject(obj.Get())) {
    474         saw_wait_start_ = true;
    475       }
    476     }
    477 
    478     void MonitorWaitFinished(Monitor* m, bool timed_out ATTRIBUTE_UNUSED)
    479         REQUIRES_SHARED(Locks::mutator_lock_) {
    480       if (IsInterestingObject(m->GetObject())) {
    481         saw_wait_finished_ = true;
    482       }
    483     }
    484 
    485     std::mutex ref_guard_;
    486     ClassReference ref_ = {nullptr, 0};
    487     bool saw_wait_start_ = false;
    488     bool saw_wait_finished_ = false;
    489   };
    490 
    491   Callback cb_;
    492 };
    493 
    494 // TODO It would be good to have more tests for this but due to the multi-threaded nature of the
    495 // callbacks this is difficult. For now the run-tests 1931 & 1932 should be sufficient.
    496 TEST_F(MonitorWaitCallbacksTest, WaitUnlocked) {
    497   ASSERT_FALSE(cb_.saw_wait_finished_);
    498   ASSERT_FALSE(cb_.saw_wait_start_);
    499   {
    500     Thread* self = Thread::Current();
    501     self->TransitionFromSuspendedToRunnable();
    502     bool started = runtime_->Start();
    503     ASSERT_TRUE(started);
    504     {
    505       ScopedObjectAccess soa(self);
    506       cb_.SetInterestingObject(
    507           soa.Decode<mirror::Class>(WellKnownClasses::java_util_Collections).Ptr());
    508       Monitor::Wait(
    509           self,
    510           // Just a random class
    511           soa.Decode<mirror::Class>(WellKnownClasses::java_util_Collections).Ptr(),
    512           /*ms*/0,
    513           /*ns*/0,
    514           /*interruptShouldThrow*/false,
    515           /*why*/kWaiting);
    516     }
    517   }
    518   ASSERT_TRUE(cb_.saw_wait_start_);
    519   ASSERT_FALSE(cb_.saw_wait_finished_);
    520 }
    521 
    522 }  // namespace art
    523