ti_thread.cc revision 983c175aa134c7f6794a4b3407d7e99536b1f7f1
1af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe/* Copyright (C) 2017 The Android Open Source Project 2af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 3af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe * 4af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe * This file implements interfaces from the file jvmti.h. This implementation 5af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe * is licensed under the same terms as the file jvmti.h. The 6af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe * copyright and license information for the file jvmti.h follows. 7af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe * 8af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved. 9af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 10af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe * 11af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe * This code is free software; you can redistribute it and/or modify it 12af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe * under the terms of the GNU General Public License version 2 only, as 13af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe * published by the Free Software Foundation. Oracle designates this 14af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe * particular file as subject to the "Classpath" exception as provided 15af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe * by Oracle in the LICENSE file that accompanied this code. 16af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe * 17af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe * This code is distributed in the hope that it will be useful, but WITHOUT 18af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 19af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 20af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe * version 2 for more details (a copy is included in the LICENSE file that 21af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe * accompanied this code). 22af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe * 23af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe * You should have received a copy of the GNU General Public License version 24af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe * 2 along with this work; if not, write to the Free Software Foundation, 25af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 26af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe * 27af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 28af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe * or visit www.oracle.com if you need additional information or have any 29af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe * questions. 30af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe */ 31af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe 32af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe#include "ti_thread.h" 33af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe 34eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe#include "android-base/strings.h" 35af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe#include "art_field.h" 36af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe#include "art_jvmti.h" 37af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe#include "base/logging.h" 38af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe#include "base/mutex.h" 39eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe#include "events-inl.h" 40f26bf2dd7d43716946ef8d4e046b9c0be36fb3a4Andreas Gampe#include "gc/system_weak.h" 41f26bf2dd7d43716946ef8d4e046b9c0be36fb3a4Andreas Gampe#include "gc_root-inl.h" 42af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe#include "jni_internal.h" 43af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe#include "mirror/class.h" 44af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe#include "mirror/object-inl.h" 45af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe#include "mirror/string.h" 46af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe#include "obj_ptr.h" 47f26bf2dd7d43716946ef8d4e046b9c0be36fb3a4Andreas Gampe#include "runtime.h" 48eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe#include "runtime_callbacks.h" 49eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe#include "ScopedLocalRef.h" 50af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe#include "scoped_thread_state_change-inl.h" 51af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe#include "thread-inl.h" 528580744607a963d408956c3eb712b0e070c139b0Andreas Gampe#include "thread_list.h" 53af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe#include "well_known_classes.h" 54af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe 55af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampenamespace openjdkjvmti { 56af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe 57eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampestruct ThreadCallback : public art::ThreadLifecycleCallback, public art::RuntimePhaseCallback { 58eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe jthread GetThreadObject(art::Thread* self) REQUIRES_SHARED(art::Locks::mutator_lock_) { 59eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe if (self->GetPeer() == nullptr) { 60eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe return nullptr; 61eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe } 62eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe return self->GetJniEnv()->AddLocalReference<jthread>(self->GetPeer()); 63eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe } 64983c175aa134c7f6794a4b3407d7e99536b1f7f1Andreas Gampe template <ArtJvmtiEvent kEvent> 65983c175aa134c7f6794a4b3407d7e99536b1f7f1Andreas Gampe void Post(art::Thread* self) REQUIRES_SHARED(art::Locks::mutator_lock_) { 66eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe DCHECK_EQ(self, art::Thread::Current()); 67eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe ScopedLocalRef<jthread> thread(self->GetJniEnv(), GetThreadObject(self)); 68e6377461540c1159e94cb45c9ade347e8e6bb52bAndreas Gampe art::ScopedThreadSuspension sts(self, art::ThreadState::kNative); 69983c175aa134c7f6794a4b3407d7e99536b1f7f1Andreas Gampe event_handler->DispatchEvent<kEvent>(self, 70983c175aa134c7f6794a4b3407d7e99536b1f7f1Andreas Gampe reinterpret_cast<JNIEnv*>(self->GetJniEnv()), 71983c175aa134c7f6794a4b3407d7e99536b1f7f1Andreas Gampe thread.get()); 72eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe } 73eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe 74eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe void ThreadStart(art::Thread* self) OVERRIDE REQUIRES_SHARED(art::Locks::mutator_lock_) { 75eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe if (!started) { 76eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe // Runtime isn't started. We only expect at most the signal handler or JIT threads to be 77eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe // started here. 78eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe if (art::kIsDebugBuild) { 79eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe std::string name; 80eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe self->GetThreadName(name); 81eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe if (name != "Signal Catcher" && !android::base::StartsWith(name, "Jit thread pool")) { 82eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe LOG(FATAL) << "Unexpected thread before start: " << name; 83eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe } 84eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe } 85eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe return; 86eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe } 87983c175aa134c7f6794a4b3407d7e99536b1f7f1Andreas Gampe Post<ArtJvmtiEvent::kThreadStart>(self); 88eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe } 89eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe 90eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe void ThreadDeath(art::Thread* self) OVERRIDE REQUIRES_SHARED(art::Locks::mutator_lock_) { 91983c175aa134c7f6794a4b3407d7e99536b1f7f1Andreas Gampe Post<ArtJvmtiEvent::kThreadEnd>(self); 92eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe } 93eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe 94eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe void NextRuntimePhase(RuntimePhase phase) OVERRIDE REQUIRES_SHARED(art::Locks::mutator_lock_) { 95eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe if (phase == RuntimePhase::kInit) { 96eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe // We moved to VMInit. Report the main thread as started (it was attached early, and must 97eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe // not be reported until Init. 98eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe started = true; 99983c175aa134c7f6794a4b3407d7e99536b1f7f1Andreas Gampe Post<ArtJvmtiEvent::kThreadStart>(art::Thread::Current()); 100eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe } 101eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe } 102eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe 103eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe EventHandler* event_handler = nullptr; 104eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe bool started = false; 105eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe}; 106eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe 107eafaf57557939bcabeb7a7388fb4951e74661a53Andreas GampeThreadCallback gThreadCallback; 108eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe 109eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampevoid ThreadUtil::Register(EventHandler* handler) { 110eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe art::Runtime* runtime = art::Runtime::Current(); 111eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe 112eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe gThreadCallback.started = runtime->IsStarted(); 113eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe gThreadCallback.event_handler = handler; 114eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe 115eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe art::ScopedThreadStateChange stsc(art::Thread::Current(), 116eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe art::ThreadState::kWaitingForDebuggerToAttach); 117eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe art::ScopedSuspendAll ssa("Add thread callback"); 118eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe runtime->GetRuntimeCallbacks()->AddThreadLifecycleCallback(&gThreadCallback); 119eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe runtime->GetRuntimeCallbacks()->AddRuntimePhaseCallback(&gThreadCallback); 120eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe} 121eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe 122eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampevoid ThreadUtil::Unregister() { 123eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe art::ScopedThreadStateChange stsc(art::Thread::Current(), 124eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe art::ThreadState::kWaitingForDebuggerToAttach); 125eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe art::ScopedSuspendAll ssa("Remove thread callback"); 126eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe art::Runtime* runtime = art::Runtime::Current(); 127eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe runtime->GetRuntimeCallbacks()->RemoveThreadLifecycleCallback(&gThreadCallback); 128eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe runtime->GetRuntimeCallbacks()->RemoveRuntimePhaseCallback(&gThreadCallback); 129eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe} 130eafaf57557939bcabeb7a7388fb4951e74661a53Andreas Gampe 131af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas GampejvmtiError ThreadUtil::GetCurrentThread(jvmtiEnv* env ATTRIBUTE_UNUSED, jthread* thread_ptr) { 132af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe art::Thread* self = art::Thread::Current(); 133af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe 134af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe art::ScopedObjectAccess soa(self); 135af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe 136af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe jthread thread_peer; 137af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe if (self->IsStillStarting()) { 138af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe thread_peer = nullptr; 139af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe } else { 140af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe thread_peer = soa.AddLocalReference<jthread>(self->GetPeer()); 141af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe } 142af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe 143af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe *thread_ptr = thread_peer; 144af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe return ERR(NONE); 145af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe} 146af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe 147af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe// Read the context classloader from a Java thread object. This is a lazy implementation 148af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe// that assumes GetThreadInfo isn't called too often. If we instead cache the ArtField, 149af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe// we will have to add synchronization as this can't be cached on startup (which is 150af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe// potentially runtime startup). 151af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampestatic art::ObjPtr<art::mirror::Object> GetContextClassLoader(art::ObjPtr<art::mirror::Object> peer) 152af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe REQUIRES_SHARED(art::Locks::mutator_lock_) { 153af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe if (peer == nullptr) { 154af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe return nullptr; 155af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe } 156af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe art::ObjPtr<art::mirror::Class> klass = peer->GetClass(); 157af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe art::ArtField* cc_field = klass->FindDeclaredInstanceField("contextClassLoader", 158af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe "Ljava/lang/ClassLoader;"); 159af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe CHECK(cc_field != nullptr); 160af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe return cc_field->GetObject(peer); 161af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe} 162af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe 163af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe// Get the native thread. The spec says a null object denotes the current thread. 164af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampestatic art::Thread* GetNativeThread(jthread thread, 165af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe const art::ScopedObjectAccessAlreadyRunnable& soa) 166af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe REQUIRES_SHARED(art::Locks::mutator_lock_) { 167af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe if (thread == nullptr) { 168af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe return art::Thread::Current(); 169af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe } 170af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe 171af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe art::MutexLock mu(soa.Self(), *art::Locks::thread_list_lock_); 172af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe return art::Thread::FromManagedThread(soa, thread); 173af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe} 174af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe 175af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas GampejvmtiError ThreadUtil::GetThreadInfo(jvmtiEnv* env, jthread thread, jvmtiThreadInfo* info_ptr) { 176af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe if (info_ptr == nullptr) { 177af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe return ERR(NULL_POINTER); 178af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe } 179af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe 180af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe art::ScopedObjectAccess soa(art::Thread::Current()); 181af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe 182af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe art::Thread* self = GetNativeThread(thread, soa); 183af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe if (self == nullptr && thread == nullptr) { 184af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe return ERR(INVALID_THREAD); 185af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe } 186af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe 187af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe JvmtiUniquePtr name_uptr; 188af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe if (self != nullptr) { 189af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe // Have a native thread object, this thread is alive. 190af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe std::string name; 191af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe self->GetThreadName(name); 192af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe jvmtiError name_result = CopyString( 193af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe env, name.c_str(), reinterpret_cast<unsigned char**>(&info_ptr->name)); 194af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe if (name_result != ERR(NONE)) { 195af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe return name_result; 196af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe } 197af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe name_uptr = MakeJvmtiUniquePtr(env, info_ptr->name); 198af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe 199af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe info_ptr->priority = self->GetNativePriority(); 200af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe 201af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe info_ptr->is_daemon = self->IsDaemon(); 202af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe 203af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe art::ObjPtr<art::mirror::Object> peer = self->GetPeer(); 204af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe 205af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe // ThreadGroup. 206af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe if (peer != nullptr) { 207af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe art::ArtField* f = art::jni::DecodeArtField(art::WellKnownClasses::java_lang_Thread_group); 208af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe CHECK(f != nullptr); 209af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe art::ObjPtr<art::mirror::Object> group = f->GetObject(peer); 210af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe info_ptr->thread_group = group == nullptr 211af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe ? nullptr 212af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe : soa.AddLocalReference<jthreadGroup>(group); 213af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe } else { 214af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe info_ptr->thread_group = nullptr; 215af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe } 216af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe 217af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe // Context classloader. 218af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe art::ObjPtr<art::mirror::Object> ccl = GetContextClassLoader(peer); 219af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe info_ptr->context_class_loader = ccl == nullptr 220af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe ? nullptr 221af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe : soa.AddLocalReference<jobject>(ccl); 222af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe } else { 223af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe // Only the peer. This thread has either not been started, or is dead. Read things from 224af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe // the Java side. 225af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe art::ObjPtr<art::mirror::Object> peer = soa.Decode<art::mirror::Object>(thread); 226af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe 227af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe // Name. 228af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe { 229af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe art::ArtField* f = art::jni::DecodeArtField(art::WellKnownClasses::java_lang_Thread_name); 230af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe CHECK(f != nullptr); 231af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe art::ObjPtr<art::mirror::Object> name = f->GetObject(peer); 232af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe std::string name_cpp; 233af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe const char* name_cstr; 234af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe if (name != nullptr) { 235af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe name_cpp = name->AsString()->ToModifiedUtf8(); 236af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe name_cstr = name_cpp.c_str(); 237af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe } else { 238af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe name_cstr = ""; 239af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe } 240af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe jvmtiError name_result = CopyString( 241af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe env, name_cstr, reinterpret_cast<unsigned char**>(&info_ptr->name)); 242af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe if (name_result != ERR(NONE)) { 243af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe return name_result; 244af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe } 245af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe name_uptr = MakeJvmtiUniquePtr(env, info_ptr->name); 246af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe } 247af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe 248af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe // Priority. 249af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe { 250af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe art::ArtField* f = art::jni::DecodeArtField(art::WellKnownClasses::java_lang_Thread_priority); 251af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe CHECK(f != nullptr); 252af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe info_ptr->priority = static_cast<jint>(f->GetInt(peer)); 253af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe } 254af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe 255af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe // Daemon. 256af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe { 257af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe art::ArtField* f = art::jni::DecodeArtField(art::WellKnownClasses::java_lang_Thread_daemon); 258af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe CHECK(f != nullptr); 259af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe info_ptr->is_daemon = f->GetBoolean(peer) == 0 ? JNI_FALSE : JNI_TRUE; 260af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe } 261af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe 262af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe // ThreadGroup. 263af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe { 264af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe art::ArtField* f = art::jni::DecodeArtField(art::WellKnownClasses::java_lang_Thread_group); 265af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe CHECK(f != nullptr); 266af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe art::ObjPtr<art::mirror::Object> group = f->GetObject(peer); 267af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe info_ptr->thread_group = group == nullptr 268af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe ? nullptr 269af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe : soa.AddLocalReference<jthreadGroup>(group); 270af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe } 271af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe 272af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe // Context classloader. 273af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe art::ObjPtr<art::mirror::Object> ccl = GetContextClassLoader(peer); 274af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe info_ptr->context_class_loader = ccl == nullptr 275af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe ? nullptr 276af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe : soa.AddLocalReference<jobject>(ccl); 277af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe } 278af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe 279af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe name_uptr.release(); 280af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe 281af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe return ERR(NONE); 282af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe} 283af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe 28472c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe// Return the thread's (or current thread, if null) thread state. Return kStarting in case 28572c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe// there's no native counterpart (thread hasn't been started, yet, or is dead). 28672c19834136c81eace33687e06f5daf92a5a7583Andreas Gampestatic art::ThreadState GetNativeThreadState(jthread thread, 28772c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe const art::ScopedObjectAccessAlreadyRunnable& soa, 28872c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe art::Thread** native_thread) 28972c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe REQUIRES_SHARED(art::Locks::mutator_lock_) { 29072c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe art::Thread* self = nullptr; 29172c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe art::MutexLock mu(soa.Self(), *art::Locks::thread_list_lock_); 29272c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe if (thread == nullptr) { 29372c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe self = art::Thread::Current(); 29472c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe } else { 29572c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe self = art::Thread::FromManagedThread(soa, thread); 29672c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe } 29772c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe *native_thread = self; 29872c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe if (self == nullptr || self->IsStillStarting()) { 29972c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe return art::ThreadState::kStarting; 30072c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe } 30172c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe return self->GetState(); 30272c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe} 30372c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe 30472c19834136c81eace33687e06f5daf92a5a7583Andreas Gampestatic jint GetJvmtiThreadStateFromInternal(art::ThreadState internal_thread_state) { 30572c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe jint jvmti_state = JVMTI_THREAD_STATE_ALIVE; 30672c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe 30772c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe if (internal_thread_state == art::ThreadState::kSuspended) { 30872c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe jvmti_state |= JVMTI_THREAD_STATE_SUSPENDED; 30972c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe // Note: We do not have data about the previous state. Otherwise we should load the previous 31072c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe // state here. 31172c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe } 31272c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe 31372c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe if (internal_thread_state == art::ThreadState::kNative) { 31472c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe jvmti_state |= JVMTI_THREAD_STATE_IN_NATIVE; 31572c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe } 31672c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe 31772c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe if (internal_thread_state == art::ThreadState::kRunnable || 31872c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe internal_thread_state == art::ThreadState::kWaitingWeakGcRootRead || 31972c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe internal_thread_state == art::ThreadState::kSuspended) { 32072c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe jvmti_state |= JVMTI_THREAD_STATE_RUNNABLE; 32172c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe } else if (internal_thread_state == art::ThreadState::kBlocked) { 32272c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe jvmti_state |= JVMTI_THREAD_STATE_BLOCKED_ON_MONITOR_ENTER; 32372c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe } else { 32472c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe // Should be in waiting state. 32572c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe jvmti_state |= JVMTI_THREAD_STATE_WAITING; 32672c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe 32772c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe if (internal_thread_state == art::ThreadState::kTimedWaiting || 32872c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe internal_thread_state == art::ThreadState::kSleeping) { 32972c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe jvmti_state |= JVMTI_THREAD_STATE_WAITING_WITH_TIMEOUT; 33072c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe } else { 33172c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe jvmti_state |= JVMTI_THREAD_STATE_WAITING_INDEFINITELY; 33272c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe } 33372c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe 33472c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe if (internal_thread_state == art::ThreadState::kSleeping) { 33572c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe jvmti_state |= JVMTI_THREAD_STATE_SLEEPING; 33672c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe } 33772c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe 33872c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe if (internal_thread_state == art::ThreadState::kTimedWaiting || 33972c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe internal_thread_state == art::ThreadState::kWaiting) { 34072c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe jvmti_state |= JVMTI_THREAD_STATE_IN_OBJECT_WAIT; 34172c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe } 34272c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe 34372c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe // TODO: PARKED. We'll have to inspect the stack. 34472c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe } 34572c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe 34672c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe return jvmti_state; 34772c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe} 34872c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe 34972c19834136c81eace33687e06f5daf92a5a7583Andreas Gampestatic jint GetJavaStateFromInternal(art::ThreadState internal_thread_state) { 35072c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe switch (internal_thread_state) { 35172c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe case art::ThreadState::kTerminated: 35272c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe return JVMTI_JAVA_LANG_THREAD_STATE_TERMINATED; 35372c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe 35472c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe case art::ThreadState::kRunnable: 35572c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe case art::ThreadState::kNative: 35672c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe case art::ThreadState::kWaitingWeakGcRootRead: 35772c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe case art::ThreadState::kSuspended: 35872c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe return JVMTI_JAVA_LANG_THREAD_STATE_RUNNABLE; 35972c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe 36072c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe case art::ThreadState::kTimedWaiting: 36172c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe case art::ThreadState::kSleeping: 36272c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe return JVMTI_JAVA_LANG_THREAD_STATE_TIMED_WAITING; 36372c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe 36472c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe case art::ThreadState::kBlocked: 36572c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe return JVMTI_JAVA_LANG_THREAD_STATE_BLOCKED; 36672c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe 36772c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe case art::ThreadState::kStarting: 36872c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe return JVMTI_JAVA_LANG_THREAD_STATE_NEW; 36972c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe 37072c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe case art::ThreadState::kWaiting: 37172c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe case art::ThreadState::kWaitingForGcToComplete: 37272c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe case art::ThreadState::kWaitingPerformingGc: 37372c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe case art::ThreadState::kWaitingForCheckPointsToRun: 37472c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe case art::ThreadState::kWaitingForDebuggerSend: 37572c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe case art::ThreadState::kWaitingForDebuggerToAttach: 37672c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe case art::ThreadState::kWaitingInMainDebuggerLoop: 37772c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe case art::ThreadState::kWaitingForDebuggerSuspension: 37872c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe case art::ThreadState::kWaitingForDeoptimization: 37972c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe case art::ThreadState::kWaitingForGetObjectsAllocated: 38072c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe case art::ThreadState::kWaitingForJniOnLoad: 38172c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe case art::ThreadState::kWaitingForSignalCatcherOutput: 38272c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe case art::ThreadState::kWaitingInMainSignalCatcherLoop: 38372c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe case art::ThreadState::kWaitingForMethodTracingStart: 38472c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe case art::ThreadState::kWaitingForVisitObjects: 38572c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe case art::ThreadState::kWaitingForGcThreadFlip: 38672c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe return JVMTI_JAVA_LANG_THREAD_STATE_WAITING; 38772c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe } 38872c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe LOG(FATAL) << "Unreachable"; 38972c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe UNREACHABLE(); 39072c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe} 39172c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe 39272c19834136c81eace33687e06f5daf92a5a7583Andreas GampejvmtiError ThreadUtil::GetThreadState(jvmtiEnv* env ATTRIBUTE_UNUSED, 39372c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe jthread thread, 39472c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe jint* thread_state_ptr) { 39572c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe if (thread_state_ptr == nullptr) { 39672c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe return ERR(NULL_POINTER); 39772c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe } 39872c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe 39972c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe art::ScopedObjectAccess soa(art::Thread::Current()); 40072c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe art::Thread* native_thread = nullptr; 40172c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe art::ThreadState internal_thread_state = GetNativeThreadState(thread, soa, &native_thread); 40272c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe 40372c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe if (internal_thread_state == art::ThreadState::kStarting) { 40472c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe if (thread == nullptr) { 40572c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe // No native thread, and no Java thread? We must be starting up. Report as wrong phase. 40672c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe return ERR(WRONG_PHASE); 40772c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe } 40872c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe 40972c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe // Need to read the Java "started" field to know whether this is starting or terminated. 41072c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe art::ObjPtr<art::mirror::Object> peer = soa.Decode<art::mirror::Object>(thread); 41172c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe art::ObjPtr<art::mirror::Class> klass = peer->GetClass(); 41272c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe art::ArtField* started_field = klass->FindDeclaredInstanceField("started", "Z"); 41372c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe CHECK(started_field != nullptr); 41472c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe bool started = started_field->GetBoolean(peer) != 0; 41572c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe constexpr jint kStartedState = JVMTI_JAVA_LANG_THREAD_STATE_NEW; 41672c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe constexpr jint kTerminatedState = JVMTI_THREAD_STATE_TERMINATED | 41772c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe JVMTI_JAVA_LANG_THREAD_STATE_TERMINATED; 41872c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe *thread_state_ptr = started ? kTerminatedState : kStartedState; 41972c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe return ERR(NONE); 42072c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe } 42172c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe DCHECK(native_thread != nullptr); 42272c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe 42372c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe // Translate internal thread state to JVMTI and Java state. 42472c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe jint jvmti_state = GetJvmtiThreadStateFromInternal(internal_thread_state); 42572c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe if (native_thread->IsInterrupted()) { 42672c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe jvmti_state |= JVMTI_THREAD_STATE_INTERRUPTED; 42772c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe } 42872c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe 42972c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe // Java state is derived from nativeGetState. 43072c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe // Note: Our implementation assigns "runnable" to suspended. As such, we will have slightly 43172c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe // different mask. However, this is for consistency with the Java view. 43272c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe jint java_state = GetJavaStateFromInternal(internal_thread_state); 43372c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe 43472c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe *thread_state_ptr = jvmti_state | java_state; 43572c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe 43672c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe return ERR(NONE); 43772c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe} 43872c19834136c81eace33687e06f5daf92a5a7583Andreas Gampe 4398580744607a963d408956c3eb712b0e070c139b0Andreas GampejvmtiError ThreadUtil::GetAllThreads(jvmtiEnv* env, 4408580744607a963d408956c3eb712b0e070c139b0Andreas Gampe jint* threads_count_ptr, 4418580744607a963d408956c3eb712b0e070c139b0Andreas Gampe jthread** threads_ptr) { 4428580744607a963d408956c3eb712b0e070c139b0Andreas Gampe if (threads_count_ptr == nullptr || threads_ptr == nullptr) { 4438580744607a963d408956c3eb712b0e070c139b0Andreas Gampe return ERR(NULL_POINTER); 4448580744607a963d408956c3eb712b0e070c139b0Andreas Gampe } 4458580744607a963d408956c3eb712b0e070c139b0Andreas Gampe 4468580744607a963d408956c3eb712b0e070c139b0Andreas Gampe art::Thread* current = art::Thread::Current(); 4478580744607a963d408956c3eb712b0e070c139b0Andreas Gampe 4488580744607a963d408956c3eb712b0e070c139b0Andreas Gampe art::ScopedObjectAccess soa(current); 4498580744607a963d408956c3eb712b0e070c139b0Andreas Gampe 4508580744607a963d408956c3eb712b0e070c139b0Andreas Gampe art::MutexLock mu(current, *art::Locks::thread_list_lock_); 4518580744607a963d408956c3eb712b0e070c139b0Andreas Gampe std::list<art::Thread*> thread_list = art::Runtime::Current()->GetThreadList()->GetList(); 4528580744607a963d408956c3eb712b0e070c139b0Andreas Gampe 4538580744607a963d408956c3eb712b0e070c139b0Andreas Gampe std::vector<art::ObjPtr<art::mirror::Object>> peers; 4548580744607a963d408956c3eb712b0e070c139b0Andreas Gampe 4558580744607a963d408956c3eb712b0e070c139b0Andreas Gampe for (art::Thread* thread : thread_list) { 4568580744607a963d408956c3eb712b0e070c139b0Andreas Gampe // Skip threads that are still starting. 4578580744607a963d408956c3eb712b0e070c139b0Andreas Gampe if (thread->IsStillStarting()) { 4588580744607a963d408956c3eb712b0e070c139b0Andreas Gampe continue; 4598580744607a963d408956c3eb712b0e070c139b0Andreas Gampe } 4608580744607a963d408956c3eb712b0e070c139b0Andreas Gampe 4618580744607a963d408956c3eb712b0e070c139b0Andreas Gampe art::ObjPtr<art::mirror::Object> peer = thread->GetPeer(); 4628580744607a963d408956c3eb712b0e070c139b0Andreas Gampe if (peer != nullptr) { 4638580744607a963d408956c3eb712b0e070c139b0Andreas Gampe peers.push_back(peer); 4648580744607a963d408956c3eb712b0e070c139b0Andreas Gampe } 4658580744607a963d408956c3eb712b0e070c139b0Andreas Gampe } 4668580744607a963d408956c3eb712b0e070c139b0Andreas Gampe 4678580744607a963d408956c3eb712b0e070c139b0Andreas Gampe if (peers.empty()) { 4688580744607a963d408956c3eb712b0e070c139b0Andreas Gampe *threads_count_ptr = 0; 4698580744607a963d408956c3eb712b0e070c139b0Andreas Gampe *threads_ptr = nullptr; 4708580744607a963d408956c3eb712b0e070c139b0Andreas Gampe } else { 4718580744607a963d408956c3eb712b0e070c139b0Andreas Gampe unsigned char* data; 4728580744607a963d408956c3eb712b0e070c139b0Andreas Gampe jvmtiError data_result = env->Allocate(peers.size() * sizeof(jthread), &data); 4738580744607a963d408956c3eb712b0e070c139b0Andreas Gampe if (data_result != ERR(NONE)) { 4748580744607a963d408956c3eb712b0e070c139b0Andreas Gampe return data_result; 4758580744607a963d408956c3eb712b0e070c139b0Andreas Gampe } 4768580744607a963d408956c3eb712b0e070c139b0Andreas Gampe jthread* threads = reinterpret_cast<jthread*>(data); 4778580744607a963d408956c3eb712b0e070c139b0Andreas Gampe for (size_t i = 0; i != peers.size(); ++i) { 4788580744607a963d408956c3eb712b0e070c139b0Andreas Gampe threads[i] = soa.AddLocalReference<jthread>(peers[i]); 4798580744607a963d408956c3eb712b0e070c139b0Andreas Gampe } 4808580744607a963d408956c3eb712b0e070c139b0Andreas Gampe 4818580744607a963d408956c3eb712b0e070c139b0Andreas Gampe *threads_count_ptr = static_cast<jint>(peers.size()); 4828580744607a963d408956c3eb712b0e070c139b0Andreas Gampe *threads_ptr = threads; 4838580744607a963d408956c3eb712b0e070c139b0Andreas Gampe } 484f26bf2dd7d43716946ef8d4e046b9c0be36fb3a4Andreas Gampe return ERR(NONE); 485f26bf2dd7d43716946ef8d4e046b9c0be36fb3a4Andreas Gampe} 486f26bf2dd7d43716946ef8d4e046b9c0be36fb3a4Andreas Gampe 487f26bf2dd7d43716946ef8d4e046b9c0be36fb3a4Andreas GampejvmtiError ThreadUtil::SetThreadLocalStorage(jvmtiEnv* env ATTRIBUTE_UNUSED, 488f26bf2dd7d43716946ef8d4e046b9c0be36fb3a4Andreas Gampe jthread thread, 489f26bf2dd7d43716946ef8d4e046b9c0be36fb3a4Andreas Gampe const void* data) { 490f26bf2dd7d43716946ef8d4e046b9c0be36fb3a4Andreas Gampe art::ScopedObjectAccess soa(art::Thread::Current()); 491f26bf2dd7d43716946ef8d4e046b9c0be36fb3a4Andreas Gampe art::Thread* self = GetNativeThread(thread, soa); 492f26bf2dd7d43716946ef8d4e046b9c0be36fb3a4Andreas Gampe if (self == nullptr && thread == nullptr) { 493f26bf2dd7d43716946ef8d4e046b9c0be36fb3a4Andreas Gampe return ERR(INVALID_THREAD); 494f26bf2dd7d43716946ef8d4e046b9c0be36fb3a4Andreas Gampe } 495f26bf2dd7d43716946ef8d4e046b9c0be36fb3a4Andreas Gampe if (self == nullptr) { 496f26bf2dd7d43716946ef8d4e046b9c0be36fb3a4Andreas Gampe return ERR(THREAD_NOT_ALIVE); 497f26bf2dd7d43716946ef8d4e046b9c0be36fb3a4Andreas Gampe } 498f26bf2dd7d43716946ef8d4e046b9c0be36fb3a4Andreas Gampe 499f26bf2dd7d43716946ef8d4e046b9c0be36fb3a4Andreas Gampe self->SetCustomTLS(data); 500f26bf2dd7d43716946ef8d4e046b9c0be36fb3a4Andreas Gampe 501f26bf2dd7d43716946ef8d4e046b9c0be36fb3a4Andreas Gampe return ERR(NONE); 502f26bf2dd7d43716946ef8d4e046b9c0be36fb3a4Andreas Gampe} 503f26bf2dd7d43716946ef8d4e046b9c0be36fb3a4Andreas Gampe 504f26bf2dd7d43716946ef8d4e046b9c0be36fb3a4Andreas GampejvmtiError ThreadUtil::GetThreadLocalStorage(jvmtiEnv* env ATTRIBUTE_UNUSED, 505f26bf2dd7d43716946ef8d4e046b9c0be36fb3a4Andreas Gampe jthread thread, 506f26bf2dd7d43716946ef8d4e046b9c0be36fb3a4Andreas Gampe void** data_ptr) { 507f26bf2dd7d43716946ef8d4e046b9c0be36fb3a4Andreas Gampe if (data_ptr == nullptr) { 508f26bf2dd7d43716946ef8d4e046b9c0be36fb3a4Andreas Gampe return ERR(NULL_POINTER); 509f26bf2dd7d43716946ef8d4e046b9c0be36fb3a4Andreas Gampe } 510f26bf2dd7d43716946ef8d4e046b9c0be36fb3a4Andreas Gampe 511f26bf2dd7d43716946ef8d4e046b9c0be36fb3a4Andreas Gampe art::ScopedObjectAccess soa(art::Thread::Current()); 512f26bf2dd7d43716946ef8d4e046b9c0be36fb3a4Andreas Gampe art::Thread* self = GetNativeThread(thread, soa); 513f26bf2dd7d43716946ef8d4e046b9c0be36fb3a4Andreas Gampe if (self == nullptr && thread == nullptr) { 514f26bf2dd7d43716946ef8d4e046b9c0be36fb3a4Andreas Gampe return ERR(INVALID_THREAD); 515f26bf2dd7d43716946ef8d4e046b9c0be36fb3a4Andreas Gampe } 516f26bf2dd7d43716946ef8d4e046b9c0be36fb3a4Andreas Gampe if (self == nullptr) { 517f26bf2dd7d43716946ef8d4e046b9c0be36fb3a4Andreas Gampe return ERR(THREAD_NOT_ALIVE); 518f26bf2dd7d43716946ef8d4e046b9c0be36fb3a4Andreas Gampe } 5198580744607a963d408956c3eb712b0e070c139b0Andreas Gampe 520f26bf2dd7d43716946ef8d4e046b9c0be36fb3a4Andreas Gampe *data_ptr = const_cast<void*>(self->GetCustomTLS()); 5218580744607a963d408956c3eb712b0e070c139b0Andreas Gampe return ERR(NONE); 5228580744607a963d408956c3eb712b0e070c139b0Andreas Gampe} 5238580744607a963d408956c3eb712b0e070c139b0Andreas Gampe 524732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampestruct AgentData { 525732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe const void* arg; 526732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe jvmtiStartFunction proc; 527732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe jthread thread; 528732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe JavaVM* java_vm; 529732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe jvmtiEnv* jvmti_env; 530732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe jint priority; 531732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe}; 532732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe 533732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampestatic void* AgentCallback(void* arg) { 534732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe std::unique_ptr<AgentData> data(reinterpret_cast<AgentData*>(arg)); 535732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe CHECK(data->thread != nullptr); 536732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe 537732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe // We already have a peer. So call our special Attach function. 538732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe art::Thread* self = art::Thread::Attach("JVMTI Agent thread", true, data->thread); 539732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe CHECK(self != nullptr); 540732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe // The name in Attach() is only for logging. Set the thread name. This is important so 541732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe // that the thread is no longer seen as starting up. 542732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe { 543732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe art::ScopedObjectAccess soa(self); 544732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe self->SetThreadName("JVMTI Agent thread"); 545732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe } 546732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe 547732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe // Release the peer. 548732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe JNIEnv* env = self->GetJniEnv(); 549732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe env->DeleteGlobalRef(data->thread); 550732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe data->thread = nullptr; 551732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe 552732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe // Run the agent code. 553732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe data->proc(data->jvmti_env, env, const_cast<void*>(data->arg)); 554732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe 555732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe // Detach the thread. 556732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe int detach_result = data->java_vm->DetachCurrentThread(); 557732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe CHECK_EQ(detach_result, 0); 558732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe 559732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe return nullptr; 560732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe} 561732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe 562732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas GampejvmtiError ThreadUtil::RunAgentThread(jvmtiEnv* jvmti_env, 563732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe jthread thread, 564732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe jvmtiStartFunction proc, 565732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe const void* arg, 566732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe jint priority) { 567732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe if (priority < JVMTI_THREAD_MIN_PRIORITY || priority > JVMTI_THREAD_MAX_PRIORITY) { 568732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe return ERR(INVALID_PRIORITY); 569732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe } 570732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe JNIEnv* env = art::Thread::Current()->GetJniEnv(); 571732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe if (thread == nullptr || !env->IsInstanceOf(thread, art::WellKnownClasses::java_lang_Thread)) { 572732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe return ERR(INVALID_THREAD); 573732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe } 574732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe if (proc == nullptr) { 575732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe return ERR(NULL_POINTER); 576732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe } 577732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe 578732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe std::unique_ptr<AgentData> data(new AgentData); 579732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe data->arg = arg; 580732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe data->proc = proc; 581732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe // We need a global ref for Java objects, as local refs will be invalid. 582732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe data->thread = env->NewGlobalRef(thread); 583732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe data->java_vm = art::Runtime::Current()->GetJavaVM(); 584732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe data->jvmti_env = jvmti_env; 585732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe data->priority = priority; 586732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe 587732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe pthread_t pthread; 588732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe int pthread_create_result = pthread_create(&pthread, 589732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe nullptr, 590732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe &AgentCallback, 591732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe reinterpret_cast<void*>(data.get())); 592732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe if (pthread_create_result != 0) { 593732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe return ERR(INTERNAL); 594732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe } 595732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe data.release(); 596732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe 597732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe return ERR(NONE); 598732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe} 599732b0aca4fb8e5ffbd518ca913cb82810b6b2061Andreas Gampe 600af13ab9586cebbfc40204179e2dd0986cc14dd84Andreas Gampe} // namespace openjdkjvmti 601