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