ti_thread.cc revision 1d8a9741d2979d09a21942fbf9107d212ce2511b
1/* Copyright (C) 2017 The Android Open Source Project 2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 3 * 4 * This file implements interfaces from the file jvmti.h. This implementation 5 * is licensed under the same terms as the file jvmti.h. The 6 * copyright and license information for the file jvmti.h follows. 7 * 8 * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved. 9 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 10 * 11 * This code is free software; you can redistribute it and/or modify it 12 * under the terms of the GNU General Public License version 2 only, as 13 * published by the Free Software Foundation. Oracle designates this 14 * particular file as subject to the "Classpath" exception as provided 15 * by Oracle in the LICENSE file that accompanied this code. 16 * 17 * This code is distributed in the hope that it will be useful, but WITHOUT 18 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 19 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 20 * version 2 for more details (a copy is included in the LICENSE file that 21 * accompanied this code). 22 * 23 * You should have received a copy of the GNU General Public License version 24 * 2 along with this work; if not, write to the Free Software Foundation, 25 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 26 * 27 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 28 * or visit www.oracle.com if you need additional information or have any 29 * questions. 30 */ 31 32#include "ti_thread.h" 33 34#include "android-base/strings.h" 35#include "art_field-inl.h" 36#include "art_jvmti.h" 37#include "base/logging.h" 38#include "base/mutex.h" 39#include "events-inl.h" 40#include "gc/system_weak.h" 41#include "gc_root-inl.h" 42#include "jni_internal.h" 43#include "mirror/class.h" 44#include "mirror/object-inl.h" 45#include "mirror/string.h" 46#include "nativehelper/ScopedLocalRef.h" 47#include "obj_ptr.h" 48#include "runtime.h" 49#include "runtime_callbacks.h" 50#include "scoped_thread_state_change-inl.h" 51#include "thread-current-inl.h" 52#include "thread_list.h" 53#include "ti_phase.h" 54#include "well_known_classes.h" 55 56namespace openjdkjvmti { 57 58art::ArtField* ThreadUtil::context_class_loader_ = nullptr; 59 60struct ThreadCallback : public art::ThreadLifecycleCallback { 61 jthread GetThreadObject(art::Thread* self) REQUIRES_SHARED(art::Locks::mutator_lock_) { 62 if (self->GetPeer() == nullptr) { 63 return nullptr; 64 } 65 return self->GetJniEnv()->AddLocalReference<jthread>(self->GetPeer()); 66 } 67 68 template <ArtJvmtiEvent kEvent> 69 void Post(art::Thread* self) REQUIRES_SHARED(art::Locks::mutator_lock_) { 70 DCHECK_EQ(self, art::Thread::Current()); 71 ScopedLocalRef<jthread> thread(self->GetJniEnv(), GetThreadObject(self)); 72 art::ScopedThreadSuspension sts(self, art::ThreadState::kNative); 73 event_handler->DispatchEvent<kEvent>(self, 74 reinterpret_cast<JNIEnv*>(self->GetJniEnv()), 75 thread.get()); 76 } 77 78 void ThreadStart(art::Thread* self) OVERRIDE REQUIRES_SHARED(art::Locks::mutator_lock_) { 79 if (!started) { 80 // Runtime isn't started. We only expect at most the signal handler or JIT threads to be 81 // started here. 82 if (art::kIsDebugBuild) { 83 std::string name; 84 self->GetThreadName(name); 85 if (name != "JDWP" && 86 name != "Signal Catcher" && 87 !android::base::StartsWith(name, "Jit thread pool")) { 88 LOG(FATAL) << "Unexpected thread before start: " << name; 89 } 90 } 91 return; 92 } 93 Post<ArtJvmtiEvent::kThreadStart>(self); 94 } 95 96 void ThreadDeath(art::Thread* self) OVERRIDE REQUIRES_SHARED(art::Locks::mutator_lock_) { 97 Post<ArtJvmtiEvent::kThreadEnd>(self); 98 } 99 100 EventHandler* event_handler = nullptr; 101 bool started = false; 102}; 103 104ThreadCallback gThreadCallback; 105 106void ThreadUtil::Register(EventHandler* handler) { 107 art::Runtime* runtime = art::Runtime::Current(); 108 109 gThreadCallback.started = runtime->IsStarted(); 110 gThreadCallback.event_handler = handler; 111 112 art::ScopedThreadStateChange stsc(art::Thread::Current(), 113 art::ThreadState::kWaitingForDebuggerToAttach); 114 art::ScopedSuspendAll ssa("Add thread callback"); 115 runtime->GetRuntimeCallbacks()->AddThreadLifecycleCallback(&gThreadCallback); 116} 117 118void ThreadUtil::VMInitEventSent() { 119 // We should have already started. 120 DCHECK(gThreadCallback.started); 121 // We moved to VMInit. Report the main thread as started (it was attached early, and must not be 122 // reported until Init. 123 gThreadCallback.Post<ArtJvmtiEvent::kThreadStart>(art::Thread::Current()); 124} 125 126void ThreadUtil::CacheData() { 127 // We must have started since it is now safe to cache our data; 128 gThreadCallback.started = true; 129 art::ScopedObjectAccess soa(art::Thread::Current()); 130 art::ObjPtr<art::mirror::Class> thread_class = 131 soa.Decode<art::mirror::Class>(art::WellKnownClasses::java_lang_Thread); 132 CHECK(thread_class != nullptr); 133 context_class_loader_ = thread_class->FindDeclaredInstanceField("contextClassLoader", 134 "Ljava/lang/ClassLoader;"); 135 CHECK(context_class_loader_ != nullptr); 136} 137 138void ThreadUtil::Unregister() { 139 art::ScopedThreadStateChange stsc(art::Thread::Current(), 140 art::ThreadState::kWaitingForDebuggerToAttach); 141 art::ScopedSuspendAll ssa("Remove thread callback"); 142 art::Runtime* runtime = art::Runtime::Current(); 143 runtime->GetRuntimeCallbacks()->RemoveThreadLifecycleCallback(&gThreadCallback); 144} 145 146jvmtiError ThreadUtil::GetCurrentThread(jvmtiEnv* env ATTRIBUTE_UNUSED, jthread* thread_ptr) { 147 art::Thread* self = art::Thread::Current(); 148 149 art::ScopedObjectAccess soa(self); 150 151 jthread thread_peer; 152 if (self->IsStillStarting()) { 153 thread_peer = nullptr; 154 } else { 155 thread_peer = soa.AddLocalReference<jthread>(self->GetPeer()); 156 } 157 158 *thread_ptr = thread_peer; 159 return ERR(NONE); 160} 161 162// Get the native thread. The spec says a null object denotes the current thread. 163art::Thread* ThreadUtil::GetNativeThread(jthread thread, 164 const art::ScopedObjectAccessAlreadyRunnable& soa) { 165 if (thread == nullptr) { 166 return art::Thread::Current(); 167 } 168 169 return art::Thread::FromManagedThread(soa, thread); 170} 171 172jvmtiError ThreadUtil::GetThreadInfo(jvmtiEnv* env, jthread thread, jvmtiThreadInfo* info_ptr) { 173 if (info_ptr == nullptr) { 174 return ERR(NULL_POINTER); 175 } 176 if (!PhaseUtil::IsLivePhase()) { 177 return JVMTI_ERROR_WRONG_PHASE; 178 } 179 180 art::Thread* self = art::Thread::Current(); 181 art::ScopedObjectAccess soa(self); 182 art::MutexLock mu(self, *art::Locks::thread_list_lock_); 183 184 art::Thread* target = GetNativeThread(thread, soa); 185 if (target == nullptr && thread == nullptr) { 186 return ERR(INVALID_THREAD); 187 } 188 189 JvmtiUniquePtr<char[]> name_uptr; 190 if (target != nullptr) { 191 // Have a native thread object, this thread is alive. 192 std::string name; 193 target->GetThreadName(name); 194 jvmtiError name_result; 195 name_uptr = CopyString(env, name.c_str(), &name_result); 196 if (name_uptr == nullptr) { 197 return name_result; 198 } 199 info_ptr->name = name_uptr.get(); 200 201 info_ptr->priority = target->GetNativePriority(); 202 203 info_ptr->is_daemon = target->IsDaemon(); 204 205 art::ObjPtr<art::mirror::Object> peer = target->GetPeerFromOtherThread(); 206 207 // ThreadGroup. 208 if (peer != nullptr) { 209 art::ArtField* f = art::jni::DecodeArtField(art::WellKnownClasses::java_lang_Thread_group); 210 CHECK(f != nullptr); 211 art::ObjPtr<art::mirror::Object> group = f->GetObject(peer); 212 info_ptr->thread_group = group == nullptr 213 ? nullptr 214 : soa.AddLocalReference<jthreadGroup>(group); 215 } else { 216 info_ptr->thread_group = nullptr; 217 } 218 219 // Context classloader. 220 DCHECK(context_class_loader_ != nullptr); 221 art::ObjPtr<art::mirror::Object> ccl = peer != nullptr 222 ? context_class_loader_->GetObject(peer) 223 : nullptr; 224 info_ptr->context_class_loader = ccl == nullptr 225 ? nullptr 226 : soa.AddLocalReference<jobject>(ccl); 227 } else { 228 // Only the peer. This thread has either not been started, or is dead. Read things from 229 // the Java side. 230 art::ObjPtr<art::mirror::Object> peer = soa.Decode<art::mirror::Object>(thread); 231 232 // Name. 233 { 234 art::ArtField* f = art::jni::DecodeArtField(art::WellKnownClasses::java_lang_Thread_name); 235 CHECK(f != nullptr); 236 art::ObjPtr<art::mirror::Object> name = f->GetObject(peer); 237 std::string name_cpp; 238 const char* name_cstr; 239 if (name != nullptr) { 240 name_cpp = name->AsString()->ToModifiedUtf8(); 241 name_cstr = name_cpp.c_str(); 242 } else { 243 name_cstr = ""; 244 } 245 jvmtiError name_result; 246 name_uptr = CopyString(env, name_cstr, &name_result); 247 if (name_uptr == nullptr) { 248 return name_result; 249 } 250 info_ptr->name = name_uptr.get(); 251 } 252 253 // Priority. 254 { 255 art::ArtField* f = art::jni::DecodeArtField(art::WellKnownClasses::java_lang_Thread_priority); 256 CHECK(f != nullptr); 257 info_ptr->priority = static_cast<jint>(f->GetInt(peer)); 258 } 259 260 // Daemon. 261 { 262 art::ArtField* f = art::jni::DecodeArtField(art::WellKnownClasses::java_lang_Thread_daemon); 263 CHECK(f != nullptr); 264 info_ptr->is_daemon = f->GetBoolean(peer) == 0 ? JNI_FALSE : JNI_TRUE; 265 } 266 267 // ThreadGroup. 268 { 269 art::ArtField* f = art::jni::DecodeArtField(art::WellKnownClasses::java_lang_Thread_group); 270 CHECK(f != nullptr); 271 art::ObjPtr<art::mirror::Object> group = f->GetObject(peer); 272 info_ptr->thread_group = group == nullptr 273 ? nullptr 274 : soa.AddLocalReference<jthreadGroup>(group); 275 } 276 277 // Context classloader. 278 DCHECK(context_class_loader_ != nullptr); 279 art::ObjPtr<art::mirror::Object> ccl = peer != nullptr 280 ? context_class_loader_->GetObject(peer) 281 : nullptr; 282 info_ptr->context_class_loader = ccl == nullptr 283 ? nullptr 284 : soa.AddLocalReference<jobject>(ccl); 285 } 286 287 name_uptr.release(); 288 289 return ERR(NONE); 290} 291 292struct InternalThreadState { 293 art::Thread* native_thread; 294 art::ThreadState art_state; 295 int thread_user_code_suspend_count; 296}; 297 298// Return the thread's (or current thread, if null) thread state. 299static InternalThreadState GetNativeThreadState(jthread thread, 300 const art::ScopedObjectAccessAlreadyRunnable& soa) 301 REQUIRES_SHARED(art::Locks::mutator_lock_) 302 REQUIRES(art::Locks::thread_list_lock_, art::Locks::user_code_suspension_lock_) { 303 art::Thread* self = nullptr; 304 if (thread == nullptr) { 305 self = art::Thread::Current(); 306 } else { 307 self = art::Thread::FromManagedThread(soa, thread); 308 } 309 InternalThreadState thread_state = {}; 310 art::MutexLock tscl_mu(soa.Self(), *art::Locks::thread_suspend_count_lock_); 311 thread_state.native_thread = self; 312 if (self == nullptr || self->IsStillStarting()) { 313 thread_state.art_state = art::ThreadState::kStarting; 314 thread_state.thread_user_code_suspend_count = 0; 315 } else { 316 thread_state.art_state = self->GetState(); 317 thread_state.thread_user_code_suspend_count = self->GetUserCodeSuspendCount(); 318 } 319 return thread_state; 320} 321 322static jint GetJvmtiThreadStateFromInternal(const InternalThreadState& state) { 323 art::ThreadState internal_thread_state = state.art_state; 324 jint jvmti_state = JVMTI_THREAD_STATE_ALIVE; 325 326 if (state.thread_user_code_suspend_count != 0) { 327 jvmti_state |= JVMTI_THREAD_STATE_SUSPENDED; 328 // Note: We do not have data about the previous state. Otherwise we should load the previous 329 // state here. 330 } 331 332 if (state.native_thread->IsInterrupted()) { 333 jvmti_state |= JVMTI_THREAD_STATE_INTERRUPTED; 334 } 335 336 if (internal_thread_state == art::ThreadState::kNative) { 337 jvmti_state |= JVMTI_THREAD_STATE_IN_NATIVE; 338 } 339 340 if (internal_thread_state == art::ThreadState::kRunnable || 341 internal_thread_state == art::ThreadState::kWaitingWeakGcRootRead || 342 internal_thread_state == art::ThreadState::kSuspended) { 343 jvmti_state |= JVMTI_THREAD_STATE_RUNNABLE; 344 } else if (internal_thread_state == art::ThreadState::kBlocked) { 345 jvmti_state |= JVMTI_THREAD_STATE_BLOCKED_ON_MONITOR_ENTER; 346 } else { 347 // Should be in waiting state. 348 jvmti_state |= JVMTI_THREAD_STATE_WAITING; 349 350 if (internal_thread_state == art::ThreadState::kTimedWaiting || 351 internal_thread_state == art::ThreadState::kSleeping) { 352 jvmti_state |= JVMTI_THREAD_STATE_WAITING_WITH_TIMEOUT; 353 } else { 354 jvmti_state |= JVMTI_THREAD_STATE_WAITING_INDEFINITELY; 355 } 356 357 if (internal_thread_state == art::ThreadState::kSleeping) { 358 jvmti_state |= JVMTI_THREAD_STATE_SLEEPING; 359 } 360 361 if (internal_thread_state == art::ThreadState::kTimedWaiting || 362 internal_thread_state == art::ThreadState::kWaiting) { 363 jvmti_state |= JVMTI_THREAD_STATE_IN_OBJECT_WAIT; 364 } 365 366 // TODO: PARKED. We'll have to inspect the stack. 367 } 368 369 return jvmti_state; 370} 371 372static jint GetJavaStateFromInternal(const InternalThreadState& state) { 373 switch (state.art_state) { 374 case art::ThreadState::kTerminated: 375 return JVMTI_JAVA_LANG_THREAD_STATE_TERMINATED; 376 377 case art::ThreadState::kRunnable: 378 case art::ThreadState::kNative: 379 case art::ThreadState::kWaitingWeakGcRootRead: 380 case art::ThreadState::kSuspended: 381 return JVMTI_JAVA_LANG_THREAD_STATE_RUNNABLE; 382 383 case art::ThreadState::kTimedWaiting: 384 case art::ThreadState::kSleeping: 385 return JVMTI_JAVA_LANG_THREAD_STATE_TIMED_WAITING; 386 387 case art::ThreadState::kBlocked: 388 return JVMTI_JAVA_LANG_THREAD_STATE_BLOCKED; 389 390 case art::ThreadState::kStarting: 391 return JVMTI_JAVA_LANG_THREAD_STATE_NEW; 392 393 case art::ThreadState::kWaiting: 394 case art::ThreadState::kWaitingForGcToComplete: 395 case art::ThreadState::kWaitingPerformingGc: 396 case art::ThreadState::kWaitingForCheckPointsToRun: 397 case art::ThreadState::kWaitingForDebuggerSend: 398 case art::ThreadState::kWaitingForDebuggerToAttach: 399 case art::ThreadState::kWaitingInMainDebuggerLoop: 400 case art::ThreadState::kWaitingForDebuggerSuspension: 401 case art::ThreadState::kWaitingForDeoptimization: 402 case art::ThreadState::kWaitingForGetObjectsAllocated: 403 case art::ThreadState::kWaitingForJniOnLoad: 404 case art::ThreadState::kWaitingForSignalCatcherOutput: 405 case art::ThreadState::kWaitingInMainSignalCatcherLoop: 406 case art::ThreadState::kWaitingForMethodTracingStart: 407 case art::ThreadState::kWaitingForVisitObjects: 408 case art::ThreadState::kWaitingForGcThreadFlip: 409 return JVMTI_JAVA_LANG_THREAD_STATE_WAITING; 410 } 411 LOG(FATAL) << "Unreachable"; 412 UNREACHABLE(); 413} 414 415// Suspends the current thread if it has any suspend requests on it. 416static void SuspendCheck(art::Thread* self) 417 REQUIRES(!art::Locks::mutator_lock_, !art::Locks::user_code_suspension_lock_) { 418 art::ScopedObjectAccess soa(self); 419 // Really this is only needed if we are in FastJNI and actually have the mutator_lock_ already. 420 self->FullSuspendCheck(); 421} 422 423jvmtiError ThreadUtil::GetThreadState(jvmtiEnv* env ATTRIBUTE_UNUSED, 424 jthread thread, 425 jint* thread_state_ptr) { 426 if (thread_state_ptr == nullptr) { 427 return ERR(NULL_POINTER); 428 } 429 430 art::Thread* self = art::Thread::Current(); 431 InternalThreadState state = {}; 432 // Loop since we need to bail out and try again if we would end up getting suspended while holding 433 // the user_code_suspension_lock_ due to a SuspendReason::kForUserCode. In this situation we 434 // release the lock, wait to get resumed and try again. 435 do { 436 SuspendCheck(self); 437 art::MutexLock ucsl_mu(self, *art::Locks::user_code_suspension_lock_); 438 { 439 art::MutexLock tscl_mu(self, *art::Locks::thread_suspend_count_lock_); 440 if (self->GetUserCodeSuspendCount() != 0) { 441 // Make sure we won't be suspended in the middle of holding the thread_suspend_count_lock_ 442 // by a user-code suspension. We retry and do another SuspendCheck to clear this. 443 continue; 444 } 445 } 446 art::ScopedObjectAccess soa(self); 447 art::MutexLock tll_mu(self, *art::Locks::thread_list_lock_); 448 state = GetNativeThreadState(thread, soa); 449 if (state.art_state == art::ThreadState::kStarting) { 450 break; 451 } 452 DCHECK(state.native_thread != nullptr); 453 454 // Translate internal thread state to JVMTI and Java state. 455 jint jvmti_state = GetJvmtiThreadStateFromInternal(state); 456 457 // Java state is derived from nativeGetState. 458 // TODO: Our implementation assigns "runnable" to suspended. As such, we will have slightly 459 // different mask if a thread got suspended due to user-code. However, this is for 460 // consistency with the Java view. 461 jint java_state = GetJavaStateFromInternal(state); 462 463 *thread_state_ptr = jvmti_state | java_state; 464 465 return ERR(NONE); 466 } while (true); 467 468 DCHECK_EQ(state.art_state, art::ThreadState::kStarting); 469 470 if (thread == nullptr) { 471 // No native thread, and no Java thread? We must be starting up. Report as wrong phase. 472 return ERR(WRONG_PHASE); 473 } 474 475 art::ScopedObjectAccess soa(self); 476 477 // Need to read the Java "started" field to know whether this is starting or terminated. 478 art::ObjPtr<art::mirror::Object> peer = soa.Decode<art::mirror::Object>(thread); 479 art::ObjPtr<art::mirror::Class> klass = peer->GetClass(); 480 art::ArtField* started_field = klass->FindDeclaredInstanceField("started", "Z"); 481 CHECK(started_field != nullptr); 482 bool started = started_field->GetBoolean(peer) != 0; 483 constexpr jint kStartedState = JVMTI_JAVA_LANG_THREAD_STATE_NEW; 484 constexpr jint kTerminatedState = JVMTI_THREAD_STATE_TERMINATED | 485 JVMTI_JAVA_LANG_THREAD_STATE_TERMINATED; 486 *thread_state_ptr = started ? kTerminatedState : kStartedState; 487 return ERR(NONE); 488} 489 490jvmtiError ThreadUtil::GetAllThreads(jvmtiEnv* env, 491 jint* threads_count_ptr, 492 jthread** threads_ptr) { 493 if (threads_count_ptr == nullptr || threads_ptr == nullptr) { 494 return ERR(NULL_POINTER); 495 } 496 497 art::Thread* current = art::Thread::Current(); 498 499 art::ScopedObjectAccess soa(current); 500 501 art::MutexLock mu(current, *art::Locks::thread_list_lock_); 502 std::list<art::Thread*> thread_list = art::Runtime::Current()->GetThreadList()->GetList(); 503 504 std::vector<art::ObjPtr<art::mirror::Object>> peers; 505 506 for (art::Thread* thread : thread_list) { 507 // Skip threads that are still starting. 508 if (thread->IsStillStarting()) { 509 continue; 510 } 511 512 art::ObjPtr<art::mirror::Object> peer = thread->GetPeerFromOtherThread(); 513 if (peer != nullptr) { 514 peers.push_back(peer); 515 } 516 } 517 518 if (peers.empty()) { 519 *threads_count_ptr = 0; 520 *threads_ptr = nullptr; 521 } else { 522 unsigned char* data; 523 jvmtiError data_result = env->Allocate(peers.size() * sizeof(jthread), &data); 524 if (data_result != ERR(NONE)) { 525 return data_result; 526 } 527 jthread* threads = reinterpret_cast<jthread*>(data); 528 for (size_t i = 0; i != peers.size(); ++i) { 529 threads[i] = soa.AddLocalReference<jthread>(peers[i]); 530 } 531 532 *threads_count_ptr = static_cast<jint>(peers.size()); 533 *threads_ptr = threads; 534 } 535 return ERR(NONE); 536} 537 538// The struct that we store in the art::Thread::custom_tls_ that maps the jvmtiEnvs to the data 539// stored with that thread. This is needed since different jvmtiEnvs are not supposed to share TLS 540// data but we only have a single slot in Thread objects to store data. 541struct JvmtiGlobalTLSData { 542 std::unordered_map<jvmtiEnv*, const void*> data GUARDED_BY(art::Locks::thread_list_lock_); 543}; 544 545static void RemoveTLSData(art::Thread* target, void* ctx) REQUIRES(art::Locks::thread_list_lock_) { 546 jvmtiEnv* env = reinterpret_cast<jvmtiEnv*>(ctx); 547 art::Locks::thread_list_lock_->AssertHeld(art::Thread::Current()); 548 JvmtiGlobalTLSData* global_tls = reinterpret_cast<JvmtiGlobalTLSData*>(target->GetCustomTLS()); 549 if (global_tls != nullptr) { 550 global_tls->data.erase(env); 551 } 552} 553 554void ThreadUtil::RemoveEnvironment(jvmtiEnv* env) { 555 art::Thread* self = art::Thread::Current(); 556 art::MutexLock mu(self, *art::Locks::thread_list_lock_); 557 art::ThreadList* list = art::Runtime::Current()->GetThreadList(); 558 list->ForEach(RemoveTLSData, env); 559} 560 561jvmtiError ThreadUtil::SetThreadLocalStorage(jvmtiEnv* env, jthread thread, const void* data) { 562 art::Thread* self = art::Thread::Current(); 563 art::ScopedObjectAccess soa(self); 564 art::MutexLock mu(self, *art::Locks::thread_list_lock_); 565 art::Thread* target = GetNativeThread(thread, soa); 566 if (target == nullptr && thread == nullptr) { 567 return ERR(INVALID_THREAD); 568 } 569 if (target == nullptr) { 570 return ERR(THREAD_NOT_ALIVE); 571 } 572 573 JvmtiGlobalTLSData* global_tls = reinterpret_cast<JvmtiGlobalTLSData*>(target->GetCustomTLS()); 574 if (global_tls == nullptr) { 575 target->SetCustomTLS(new JvmtiGlobalTLSData); 576 global_tls = reinterpret_cast<JvmtiGlobalTLSData*>(target->GetCustomTLS()); 577 } 578 579 global_tls->data[env] = data; 580 581 return ERR(NONE); 582} 583 584jvmtiError ThreadUtil::GetThreadLocalStorage(jvmtiEnv* env, 585 jthread thread, 586 void** data_ptr) { 587 if (data_ptr == nullptr) { 588 return ERR(NULL_POINTER); 589 } 590 591 art::Thread* self = art::Thread::Current(); 592 art::ScopedObjectAccess soa(self); 593 art::MutexLock mu(self, *art::Locks::thread_list_lock_); 594 art::Thread* target = GetNativeThread(thread, soa); 595 if (target == nullptr && thread == nullptr) { 596 return ERR(INVALID_THREAD); 597 } 598 if (target == nullptr) { 599 return ERR(THREAD_NOT_ALIVE); 600 } 601 602 JvmtiGlobalTLSData* global_tls = reinterpret_cast<JvmtiGlobalTLSData*>(target->GetCustomTLS()); 603 if (global_tls == nullptr) { 604 *data_ptr = nullptr; 605 return OK; 606 } 607 auto it = global_tls->data.find(env); 608 if (it != global_tls->data.end()) { 609 *data_ptr = const_cast<void*>(it->second); 610 } else { 611 *data_ptr = nullptr; 612 } 613 614 return ERR(NONE); 615} 616 617struct AgentData { 618 const void* arg; 619 jvmtiStartFunction proc; 620 jthread thread; 621 JavaVM* java_vm; 622 jvmtiEnv* jvmti_env; 623 jint priority; 624}; 625 626static void* AgentCallback(void* arg) { 627 std::unique_ptr<AgentData> data(reinterpret_cast<AgentData*>(arg)); 628 CHECK(data->thread != nullptr); 629 630 // We already have a peer. So call our special Attach function. 631 art::Thread* self = art::Thread::Attach("JVMTI Agent thread", true, data->thread); 632 CHECK(self != nullptr); 633 // The name in Attach() is only for logging. Set the thread name. This is important so 634 // that the thread is no longer seen as starting up. 635 { 636 art::ScopedObjectAccess soa(self); 637 self->SetThreadName("JVMTI Agent thread"); 638 } 639 640 // Release the peer. 641 JNIEnv* env = self->GetJniEnv(); 642 env->DeleteGlobalRef(data->thread); 643 data->thread = nullptr; 644 645 // Run the agent code. 646 data->proc(data->jvmti_env, env, const_cast<void*>(data->arg)); 647 648 // Detach the thread. 649 int detach_result = data->java_vm->DetachCurrentThread(); 650 CHECK_EQ(detach_result, 0); 651 652 return nullptr; 653} 654 655jvmtiError ThreadUtil::RunAgentThread(jvmtiEnv* jvmti_env, 656 jthread thread, 657 jvmtiStartFunction proc, 658 const void* arg, 659 jint priority) { 660 if (priority < JVMTI_THREAD_MIN_PRIORITY || priority > JVMTI_THREAD_MAX_PRIORITY) { 661 return ERR(INVALID_PRIORITY); 662 } 663 JNIEnv* env = art::Thread::Current()->GetJniEnv(); 664 if (thread == nullptr || !env->IsInstanceOf(thread, art::WellKnownClasses::java_lang_Thread)) { 665 return ERR(INVALID_THREAD); 666 } 667 if (proc == nullptr) { 668 return ERR(NULL_POINTER); 669 } 670 671 std::unique_ptr<AgentData> data(new AgentData); 672 data->arg = arg; 673 data->proc = proc; 674 // We need a global ref for Java objects, as local refs will be invalid. 675 data->thread = env->NewGlobalRef(thread); 676 data->java_vm = art::Runtime::Current()->GetJavaVM(); 677 data->jvmti_env = jvmti_env; 678 data->priority = priority; 679 680 pthread_t pthread; 681 int pthread_create_result = pthread_create(&pthread, 682 nullptr, 683 &AgentCallback, 684 reinterpret_cast<void*>(data.get())); 685 if (pthread_create_result != 0) { 686 return ERR(INTERNAL); 687 } 688 data.release(); 689 690 return ERR(NONE); 691} 692 693jvmtiError ThreadUtil::SuspendOther(art::Thread* self, 694 jthread target_jthread) { 695 // Loop since we need to bail out and try again if we would end up getting suspended while holding 696 // the user_code_suspension_lock_ due to a SuspendReason::kForUserCode. In this situation we 697 // release the lock, wait to get resumed and try again. 698 do { 699 // Suspend ourself if we have any outstanding suspends. This is so we won't suspend due to 700 // another SuspendThread in the middle of suspending something else potentially causing a 701 // deadlock. We need to do this in the loop because if we ended up back here then we had 702 // outstanding SuspendReason::kForUserCode suspensions and we should wait for them to be cleared 703 // before continuing. 704 SuspendCheck(self); 705 art::MutexLock mu(self, *art::Locks::user_code_suspension_lock_); 706 { 707 art::MutexLock thread_suspend_count_mu(self, *art::Locks::thread_suspend_count_lock_); 708 // Make sure we won't be suspended in the middle of holding the thread_suspend_count_lock_ by 709 // a user-code suspension. We retry and do another SuspendCheck to clear this. 710 if (self->GetUserCodeSuspendCount() != 0) { 711 continue; 712 } 713 // We are not going to be suspended by user code from now on. 714 } 715 { 716 art::ScopedObjectAccess soa(self); 717 art::MutexLock thread_list_mu(self, *art::Locks::thread_list_lock_); 718 art::Thread* target = GetNativeThread(target_jthread, soa); 719 art::ThreadState state = target->GetState(); 720 if (state == art::ThreadState::kTerminated || state == art::ThreadState::kStarting) { 721 return ERR(THREAD_NOT_ALIVE); 722 } else { 723 art::MutexLock thread_suspend_count_mu(self, *art::Locks::thread_suspend_count_lock_); 724 if (target->GetUserCodeSuspendCount() != 0) { 725 return ERR(THREAD_SUSPENDED); 726 } 727 } 728 } 729 bool timeout = true; 730 art::Thread* ret_target = art::Runtime::Current()->GetThreadList()->SuspendThreadByPeer( 731 target_jthread, 732 /* request_suspension */ true, 733 art::SuspendReason::kForUserCode, 734 &timeout); 735 if (ret_target == nullptr && !timeout) { 736 // TODO It would be good to get more information about why exactly the thread failed to 737 // suspend. 738 return ERR(INTERNAL); 739 } else if (!timeout) { 740 // we didn't time out and got a result. 741 return OK; 742 } 743 // We timed out. Just go around and try again. 744 } while (true); 745 UNREACHABLE(); 746} 747 748jvmtiError ThreadUtil::SuspendSelf(art::Thread* self) { 749 CHECK(self == art::Thread::Current()); 750 { 751 art::MutexLock mu(self, *art::Locks::user_code_suspension_lock_); 752 art::MutexLock thread_list_mu(self, *art::Locks::thread_suspend_count_lock_); 753 if (self->GetUserCodeSuspendCount() != 0) { 754 // This can only happen if we race with another thread to suspend 'self' and we lose. 755 return ERR(THREAD_SUSPENDED); 756 } 757 // We shouldn't be able to fail this. 758 if (!self->ModifySuspendCount(self, +1, nullptr, art::SuspendReason::kForUserCode)) { 759 // TODO More specific error would be nice. 760 return ERR(INTERNAL); 761 } 762 } 763 // Once we have requested the suspend we actually go to sleep. We need to do this after releasing 764 // the suspend_lock to make sure we can be woken up. This call gains the mutator lock causing us 765 // to go to sleep until we are resumed. 766 SuspendCheck(self); 767 return OK; 768} 769 770jvmtiError ThreadUtil::SuspendThread(jvmtiEnv* env ATTRIBUTE_UNUSED, jthread thread) { 771 art::Thread* self = art::Thread::Current(); 772 bool target_is_self = false; 773 { 774 art::ScopedObjectAccess soa(self); 775 art::MutexLock mu(self, *art::Locks::thread_list_lock_); 776 art::Thread* target = GetNativeThread(thread, soa); 777 if (target == nullptr) { 778 return ERR(INVALID_THREAD); 779 } else if (target == self) { 780 target_is_self = true; 781 } 782 } 783 if (target_is_self) { 784 return SuspendSelf(self); 785 } else { 786 return SuspendOther(self, thread); 787 } 788} 789 790jvmtiError ThreadUtil::ResumeThread(jvmtiEnv* env ATTRIBUTE_UNUSED, 791 jthread thread) { 792 if (thread == nullptr) { 793 return ERR(NULL_POINTER); 794 } 795 art::Thread* self = art::Thread::Current(); 796 art::Thread* target; 797 // Retry until we know we won't get suspended by user code while resuming something. 798 do { 799 SuspendCheck(self); 800 art::MutexLock ucsl_mu(self, *art::Locks::user_code_suspension_lock_); 801 { 802 art::MutexLock tscl_mu(self, *art::Locks::thread_suspend_count_lock_); 803 // Make sure we won't be suspended in the middle of holding the thread_suspend_count_lock_ by 804 // a user-code suspension. We retry and do another SuspendCheck to clear this. 805 if (self->GetUserCodeSuspendCount() != 0) { 806 continue; 807 } 808 } 809 // From now on we know we cannot get suspended by user-code. 810 { 811 // NB This does a SuspendCheck (during thread state change) so we need to make sure we don't 812 // have the 'suspend_lock' locked here. 813 art::ScopedObjectAccess soa(self); 814 art::MutexLock tll_mu(self, *art::Locks::thread_list_lock_); 815 target = GetNativeThread(thread, soa); 816 if (target == nullptr) { 817 return ERR(INVALID_THREAD); 818 } else if (target == self) { 819 // We would have paused until we aren't suspended anymore due to the ScopedObjectAccess so 820 // we can just return THREAD_NOT_SUSPENDED. Unfortunately we cannot do any real DCHECKs 821 // about current state since it's all concurrent. 822 return ERR(THREAD_NOT_SUSPENDED); 823 } else if (target->GetState() == art::ThreadState::kTerminated) { 824 return ERR(THREAD_NOT_ALIVE); 825 } 826 // The JVMTI spec requires us to return THREAD_NOT_SUSPENDED if it is alive but we really 827 // cannot tell why resume failed. 828 { 829 art::MutexLock thread_suspend_count_mu(self, *art::Locks::thread_suspend_count_lock_); 830 if (target->GetUserCodeSuspendCount() == 0) { 831 return ERR(THREAD_NOT_SUSPENDED); 832 } 833 } 834 } 835 // It is okay that we don't have a thread_list_lock here since we know that the thread cannot 836 // die since it is currently held suspended by a SuspendReason::kForUserCode suspend. 837 DCHECK(target != self); 838 if (!art::Runtime::Current()->GetThreadList()->Resume(target, 839 art::SuspendReason::kForUserCode)) { 840 // TODO Give a better error. 841 // This is most likely THREAD_NOT_SUSPENDED but we cannot really be sure. 842 return ERR(INTERNAL); 843 } else { 844 return OK; 845 } 846 } while (true); 847} 848 849// Suspends all the threads in the list at the same time. Getting this behavior is a little tricky 850// since we can have threads in the list multiple times. This generally doesn't matter unless the 851// current thread is present multiple times. In that case we need to suspend only once and either 852// return the same error code in all the other slots if it failed or return ERR(THREAD_SUSPENDED) if 853// it didn't. We also want to handle the current thread last to make the behavior of the code 854// simpler to understand. 855jvmtiError ThreadUtil::SuspendThreadList(jvmtiEnv* env, 856 jint request_count, 857 const jthread* threads, 858 jvmtiError* results) { 859 if (request_count == 0) { 860 return ERR(ILLEGAL_ARGUMENT); 861 } else if (results == nullptr || threads == nullptr) { 862 return ERR(NULL_POINTER); 863 } 864 // This is the list of the indexes in 'threads' and 'results' that correspond to the currently 865 // running thread. These indexes we need to handle specially since we need to only actually 866 // suspend a single time. 867 std::vector<jint> current_thread_indexes; 868 art::Thread* self = art::Thread::Current(); 869 for (jint i = 0; i < request_count; i++) { 870 { 871 art::ScopedObjectAccess soa(self); 872 art::MutexLock mu(self, *art::Locks::thread_list_lock_); 873 if (threads[i] == nullptr || GetNativeThread(threads[i], soa) == self) { 874 current_thread_indexes.push_back(i); 875 continue; 876 } 877 } 878 results[i] = env->SuspendThread(threads[i]); 879 } 880 if (!current_thread_indexes.empty()) { 881 jint first_current_thread_index = current_thread_indexes[0]; 882 // Suspend self. 883 jvmtiError res = env->SuspendThread(threads[first_current_thread_index]); 884 results[first_current_thread_index] = res; 885 // Fill in the rest of the error values as appropriate. 886 jvmtiError other_results = (res != OK) ? res : ERR(THREAD_SUSPENDED); 887 for (auto it = ++current_thread_indexes.begin(); it != current_thread_indexes.end(); ++it) { 888 results[*it] = other_results; 889 } 890 } 891 return OK; 892} 893 894jvmtiError ThreadUtil::ResumeThreadList(jvmtiEnv* env, 895 jint request_count, 896 const jthread* threads, 897 jvmtiError* results) { 898 if (request_count == 0) { 899 return ERR(ILLEGAL_ARGUMENT); 900 } else if (results == nullptr || threads == nullptr) { 901 return ERR(NULL_POINTER); 902 } 903 for (jint i = 0; i < request_count; i++) { 904 results[i] = env->ResumeThread(threads[i]); 905 } 906 return OK; 907} 908 909} // namespace openjdkjvmti 910