• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/logging.h>
35 
36 #include "art_field-inl.h"
37 #include "art_jvmti.h"
38 #include "base/mutex.h"
39 #include "deopt_manager.h"
40 #include "events-inl.h"
41 #include "gc/collector_type.h"
42 #include "gc/gc_cause.h"
43 #include "gc/scoped_gc_critical_section.h"
44 #include "gc/system_weak.h"
45 #include "gc_root-inl.h"
46 #include "jni/jni_internal.h"
47 #include "metrics/reporter.h"
48 #include "mirror/class.h"
49 #include "mirror/object-inl.h"
50 #include "mirror/string.h"
51 #include "mirror/throwable.h"
52 #include "nativehelper/scoped_local_ref.h"
53 #include "nativehelper/scoped_utf_chars.h"
54 #include "obj_ptr.h"
55 #include "runtime.h"
56 #include "runtime_callbacks.h"
57 #include "scoped_thread_state_change-inl.h"
58 #include "thread-current-inl.h"
59 #include "thread_list.h"
60 #include "ti_phase.h"
61 #include "well_known_classes-inl.h"
62 
63 namespace openjdkjvmti {
64 
65 static const char* kJvmtiTlsKey = "JvmtiTlsKey";
66 
67 art::ArtField* ThreadUtil::context_class_loader_ = nullptr;
68 
ScopedNoUserCodeSuspension(art::Thread * self)69 ScopedNoUserCodeSuspension::ScopedNoUserCodeSuspension(art::Thread* self) : self_(self) {
70   DCHECK_EQ(self, art::Thread::Current());
71   // Loop until we both have the user_code_suspension_locK_ and don't have any pending user_code
72   // suspensions.
73   do {
74     art::Locks::user_code_suspension_lock_->AssertNotHeld(self_);
75     ThreadUtil::SuspendCheck(self_);
76 
77     art::Locks::user_code_suspension_lock_->ExclusiveLock(self_);
78     if (ThreadUtil::WouldSuspendForUserCodeLocked(self_)) {
79       art::Locks::user_code_suspension_lock_->ExclusiveUnlock(self_);
80       continue;
81     }
82 
83     art::Locks::user_code_suspension_lock_->AssertHeld(self_);
84 
85     return;
86   } while (true);
87 }
88 
~ScopedNoUserCodeSuspension()89 ScopedNoUserCodeSuspension::~ScopedNoUserCodeSuspension() {
90   art::Locks::user_code_suspension_lock_->ExclusiveUnlock(self_);
91 }
92 
93 struct ThreadCallback : public art::ThreadLifecycleCallback {
GetThreadObjectopenjdkjvmti::ThreadCallback94   jthread GetThreadObject(art::Thread* self) REQUIRES_SHARED(art::Locks::mutator_lock_) {
95     if (self->GetPeer() == nullptr) {
96       return nullptr;
97     }
98     return self->GetJniEnv()->AddLocalReference<jthread>(self->GetPeer());
99   }
100 
101   template <ArtJvmtiEvent kEvent>
Postopenjdkjvmti::ThreadCallback102   void Post(art::Thread* self) REQUIRES_SHARED(art::Locks::mutator_lock_) {
103     DCHECK_EQ(self, art::Thread::Current());
104     ScopedLocalRef<jthread> thread(self->GetJniEnv(), GetThreadObject(self));
105     art::ScopedThreadSuspension sts(self, art::ThreadState::kNative);
106     event_handler->DispatchEvent<kEvent>(self,
107                                          reinterpret_cast<JNIEnv*>(self->GetJniEnv()),
108                                          thread.get());
109   }
110 
ThreadStartopenjdkjvmti::ThreadCallback111   void ThreadStart(art::Thread* self) override REQUIRES_SHARED(art::Locks::mutator_lock_) {
112     // Needs to be checked first because we might start these threads before we actually send the
113     // VMInit event.
114     if (self->IsSystemDaemon()) {
115       // System daemon threads are things like the finalizer or gc thread. It would be dangerous to
116       // allow agents to get in the way of these threads starting up. These threads include things
117       // like the HeapTaskDaemon and the finalizer daemon.
118       //
119       // This event can happen during the time before VMInit or just after zygote fork. Since the
120       // second is hard to distinguish we unfortunately cannot really check the state here.
121       return;
122     }
123     if (!started) {
124       // Runtime isn't started. We only expect at most the signal handler or JIT threads to be
125       // started here; this includes the perfetto_hprof_listener signal handler thread for
126       // perfetto_hprof, as well as the metrics background reporting thread.
127       if (art::kIsDebugBuild) {
128         std::string name;
129         self->GetThreadName(name);
130         if (name != "JDWP" && name != "Signal Catcher" && name != "perfetto_hprof_listener" &&
131             name != art::metrics::MetricsReporter::kBackgroundThreadName &&
132             !name.starts_with("Jit thread pool") &&
133             !name.starts_with("Heap thread pool worker thread") &&
134             !name.starts_with("Runtime worker thread")) {
135           LOG(FATAL) << "Unexpected thread before start: " << name << " id: "
136                      << self->GetThreadId();
137         }
138       }
139       return;
140     }
141     Post<ArtJvmtiEvent::kThreadStart>(self);
142   }
143 
ThreadDeathopenjdkjvmti::ThreadCallback144   void ThreadDeath(art::Thread* self) override REQUIRES_SHARED(art::Locks::mutator_lock_) {
145     Post<ArtJvmtiEvent::kThreadEnd>(self);
146   }
147 
148   EventHandler* event_handler = nullptr;
149   bool started = false;
150 };
151 
152 ThreadCallback gThreadCallback;
153 
Register(EventHandler * handler)154 void ThreadUtil::Register(EventHandler* handler) {
155   art::Runtime* runtime = art::Runtime::Current();
156 
157   gThreadCallback.started = runtime->IsStarted();
158   gThreadCallback.event_handler = handler;
159 
160   art::ScopedThreadStateChange stsc(art::Thread::Current(),
161                                     art::ThreadState::kWaitingForDebuggerToAttach);
162   art::ScopedSuspendAll ssa("Add thread callback");
163   runtime->GetRuntimeCallbacks()->AddThreadLifecycleCallback(&gThreadCallback);
164 }
165 
VMInitEventSent()166 void ThreadUtil::VMInitEventSent() {
167   // We should have already started.
168   DCHECK(gThreadCallback.started);
169   // We moved to VMInit. Report the main thread as started (it was attached early, and must not be
170   // reported until Init.
171   gThreadCallback.Post<ArtJvmtiEvent::kThreadStart>(art::Thread::Current());
172 }
173 
174 
WaitForSystemDaemonStart(art::Thread * self)175 static void WaitForSystemDaemonStart(art::Thread* self) REQUIRES_SHARED(art::Locks::mutator_lock_) {
176   art::WellKnownClasses::java_lang_Daemons_waitForDaemonStart->InvokeStatic<'V'>(self);
177   if (self->IsExceptionPending()) {
178     LOG(WARNING) << "Exception occurred when waiting for system daemons to start: "
179                  << self->GetException()->Dump();
180     self->ClearException();
181   }
182 }
183 
CacheData()184 void ThreadUtil::CacheData() {
185   // We must have started since it is now safe to cache our data;
186   gThreadCallback.started = true;
187   art::Thread* self = art::Thread::Current();
188   art::ScopedObjectAccess soa(self);
189   art::ObjPtr<art::mirror::Class> thread_class = art::WellKnownClasses::java_lang_Thread.Get();
190   CHECK(thread_class != nullptr);
191   context_class_loader_ = thread_class->FindDeclaredInstanceField("contextClassLoader",
192                                                                   "Ljava/lang/ClassLoader;");
193   CHECK(context_class_loader_ != nullptr);
194   // Now wait for all required system threads to come up before allowing the rest of loading to
195   // continue.
196   WaitForSystemDaemonStart(self);
197 }
198 
Unregister()199 void ThreadUtil::Unregister() {
200   art::ScopedThreadStateChange stsc(art::Thread::Current(),
201                                     art::ThreadState::kWaitingForDebuggerToAttach);
202   art::ScopedSuspendAll ssa("Remove thread callback");
203   art::Runtime* runtime = art::Runtime::Current();
204   runtime->GetRuntimeCallbacks()->RemoveThreadLifecycleCallback(&gThreadCallback);
205 }
206 
GetCurrentThread(jvmtiEnv * env,jthread * thread_ptr)207 jvmtiError ThreadUtil::GetCurrentThread([[maybe_unused]] jvmtiEnv* env, jthread* thread_ptr) {
208   art::Thread* self = art::Thread::Current();
209 
210   art::ScopedObjectAccess soa(self);
211 
212   jthread thread_peer;
213   if (self->IsStillStarting()) {
214     thread_peer = nullptr;
215   } else {
216     thread_peer = soa.AddLocalReference<jthread>(self->GetPeer());
217   }
218 
219   *thread_ptr = thread_peer;
220   return ERR(NONE);
221 }
222 
223 // Get the native thread. The spec says a null object denotes the current thread.
GetNativeThread(jthread thread,const art::ScopedObjectAccessAlreadyRunnable & soa,art::Thread ** thr,jvmtiError * err)224 bool ThreadUtil::GetNativeThread(jthread thread,
225                                  const art::ScopedObjectAccessAlreadyRunnable& soa,
226                                  /*out*/ art::Thread** thr,
227                                  /*out*/ jvmtiError* err) {
228   art::ScopedExceptionStorage sse(soa.Self());
229   if (thread == nullptr) {
230     *thr = art::Thread::Current();
231     return true;
232   }
233   art::ObjPtr<art::mirror::Object> othread = soa.Decode<art::mirror::Object>(thread);
234   if (!othread->InstanceOf(art::WellKnownClasses::java_lang_Thread.Get())) {
235     *err = ERR(INVALID_THREAD);
236     return false;
237   } else {
238     *thr = art::Thread::FromManagedThread(soa, thread);
239     return true;
240   }
241 }
242 
GetAliveNativeThread(jthread thread,const art::ScopedObjectAccessAlreadyRunnable & soa,art::Thread ** thr,jvmtiError * err)243 bool ThreadUtil::GetAliveNativeThread(jthread thread,
244                                       const art::ScopedObjectAccessAlreadyRunnable& soa,
245                                       /*out*/ art::Thread** thr,
246                                       /*out*/ jvmtiError* err) {
247   if (!GetNativeThread(thread, soa, thr, err)) {
248     return false;
249   } else if (*thr == nullptr || (*thr)->GetState() == art::ThreadState::kTerminated) {
250     *err = ERR(THREAD_NOT_ALIVE);
251     return false;
252   } else {
253     return true;
254   }
255 }
256 
GetThreadInfo(jvmtiEnv * env,jthread thread,jvmtiThreadInfo * info_ptr)257 jvmtiError ThreadUtil::GetThreadInfo(jvmtiEnv* env, jthread thread, jvmtiThreadInfo* info_ptr) {
258   if (info_ptr == nullptr) {
259     return ERR(NULL_POINTER);
260   }
261   if (!PhaseUtil::IsLivePhase()) {
262     return JVMTI_ERROR_WRONG_PHASE;
263   }
264 
265   art::Thread* self = art::Thread::Current();
266   art::ScopedObjectAccess soa(self);
267   art::MutexLock mu(self, *art::Locks::thread_list_lock_);
268 
269   art::Thread* target;
270   jvmtiError err = ERR(INTERNAL);
271   if (!GetNativeThread(thread, soa, &target, &err)) {
272     return err;
273   }
274 
275   JvmtiUniquePtr<char[]> name_uptr;
276   if (target != nullptr) {
277     // Have a native thread object, this thread is alive.
278     std::string name;
279     target->GetThreadName(name);
280     jvmtiError name_result;
281     name_uptr = CopyString(env, name.c_str(), &name_result);
282     if (name_uptr == nullptr) {
283       return name_result;
284     }
285     info_ptr->name = name_uptr.get();
286 
287     info_ptr->priority = target->GetNativePriority();
288 
289     info_ptr->is_daemon = target->IsDaemon();
290 
291     art::ObjPtr<art::mirror::Object> peer = target->LockedGetPeerFromOtherThread();
292     // *target may be invalid here since we may have temporarily released thread_list_lock_.
293     target = nullptr;  // Value should not be used.
294 
295     // ThreadGroup.
296     if (peer != nullptr) {
297       art::ArtField* f = art::WellKnownClasses::java_lang_Thread_group;
298       CHECK(f != nullptr);
299       art::ObjPtr<art::mirror::Object> group = f->GetObject(peer);
300       info_ptr->thread_group = group == nullptr
301                                    ? nullptr
302                                    : soa.AddLocalReference<jthreadGroup>(group);
303     } else {
304       info_ptr->thread_group = nullptr;
305     }
306 
307     // Context classloader.
308     DCHECK(context_class_loader_ != nullptr);
309     art::ObjPtr<art::mirror::Object> ccl = peer != nullptr
310         ? context_class_loader_->GetObject(peer)
311         : nullptr;
312     info_ptr->context_class_loader = ccl == nullptr
313                                          ? nullptr
314                                          : soa.AddLocalReference<jobject>(ccl);
315   } else {
316     // Only the peer. This thread has either not been started, or is dead. Read things from
317     // the Java side.
318     art::ObjPtr<art::mirror::Object> peer = soa.Decode<art::mirror::Object>(thread);
319 
320     // Name.
321     {
322       art::ArtField* f = art::WellKnownClasses::java_lang_Thread_name;
323       CHECK(f != nullptr);
324       art::ObjPtr<art::mirror::Object> name = f->GetObject(peer);
325       std::string name_cpp;
326       const char* name_cstr;
327       if (name != nullptr) {
328         name_cpp = name->AsString()->ToModifiedUtf8();
329         name_cstr = name_cpp.c_str();
330       } else {
331         name_cstr = "";
332       }
333       jvmtiError name_result;
334       name_uptr = CopyString(env, name_cstr, &name_result);
335       if (name_uptr == nullptr) {
336         return name_result;
337       }
338       info_ptr->name = name_uptr.get();
339     }
340 
341     // Priority.
342     {
343       art::ArtField* f = art::WellKnownClasses::java_lang_Thread_priority;
344       CHECK(f != nullptr);
345       info_ptr->priority = static_cast<jint>(f->GetInt(peer));
346     }
347 
348     // Daemon.
349     {
350       art::ArtField* f = art::WellKnownClasses::java_lang_Thread_daemon;
351       CHECK(f != nullptr);
352       info_ptr->is_daemon = f->GetBoolean(peer) == 0 ? JNI_FALSE : JNI_TRUE;
353     }
354 
355     // ThreadGroup.
356     {
357       art::ArtField* f = art::WellKnownClasses::java_lang_Thread_group;
358       CHECK(f != nullptr);
359       art::ObjPtr<art::mirror::Object> group = f->GetObject(peer);
360       info_ptr->thread_group = group == nullptr
361                                    ? nullptr
362                                    : soa.AddLocalReference<jthreadGroup>(group);
363     }
364 
365     // Context classloader.
366     DCHECK(context_class_loader_ != nullptr);
367     art::ObjPtr<art::mirror::Object> ccl = peer != nullptr
368         ? context_class_loader_->GetObject(peer)
369         : nullptr;
370     info_ptr->context_class_loader = ccl == nullptr
371                                          ? nullptr
372                                          : soa.AddLocalReference<jobject>(ccl);
373   }
374 
375   name_uptr.release();
376 
377   return ERR(NONE);
378 }
379 
380 struct InternalThreadState {
381   art::Thread* native_thread;
382   art::ThreadState art_state;
383   int thread_user_code_suspend_count;
384 };
385 
386 // Return the thread's (or current thread, if null) thread state.
GetNativeThreadState(art::Thread * target)387 static InternalThreadState GetNativeThreadState(art::Thread* target)
388     REQUIRES_SHARED(art::Locks::mutator_lock_)
389     REQUIRES(art::Locks::thread_list_lock_, art::Locks::user_code_suspension_lock_) {
390   InternalThreadState thread_state = {};
391   art::MutexLock tscl_mu(art::Thread::Current(), *art::Locks::thread_suspend_count_lock_);
392   thread_state.native_thread = target;
393   if (target == nullptr || target->IsStillStarting()) {
394     thread_state.art_state = art::ThreadState::kStarting;
395     thread_state.thread_user_code_suspend_count = 0;
396   } else {
397     thread_state.art_state = target->GetState();
398     thread_state.thread_user_code_suspend_count = target->GetUserCodeSuspendCount();
399   }
400   return thread_state;
401 }
402 
GetJvmtiThreadStateFromInternal(const InternalThreadState & state)403 static jint GetJvmtiThreadStateFromInternal(const InternalThreadState& state) {
404   art::ThreadState internal_thread_state = state.art_state;
405   jint jvmti_state = JVMTI_THREAD_STATE_ALIVE;
406 
407   if (state.thread_user_code_suspend_count != 0) {
408     // Suspended can be set with any thread state so check it here. Even if the thread isn't in
409     // kSuspended state it will move to that once it hits a checkpoint so we can still set this.
410     jvmti_state |= JVMTI_THREAD_STATE_SUSPENDED;
411     // Note: We do not have data about the previous state. Otherwise we should load the previous
412     //       state here.
413   }
414 
415   if (state.native_thread->IsInterrupted()) {
416     // Interrupted can be set with any thread state so check it here.
417     jvmti_state |= JVMTI_THREAD_STATE_INTERRUPTED;
418   }
419 
420   // Enumerate all the thread states and fill in the other bits. This contains the results of
421   // following the decision tree in the JVMTI spec GetThreadState documentation.
422   switch (internal_thread_state) {
423     case art::ThreadState::kRunnable:
424     case art::ThreadState::kWaitingWeakGcRootRead:
425     case art::ThreadState::kSuspended:
426       // These are all simply runnable.
427       // kRunnable is self-explanatory.
428       // kWaitingWeakGcRootRead is set during some operations with strings due to the intern-table
429       // so we want to keep it marked as runnable.
430       // kSuspended we don't mark since if we don't have a user_code_suspend_count then it is done
431       // by the GC and not a JVMTI suspension, which means it cannot be removed by ResumeThread.
432       jvmti_state |= JVMTI_THREAD_STATE_RUNNABLE;
433       break;
434     case art::ThreadState::kNative:
435       // kNative means native and runnable. Technically THREAD_STATE_IN_NATIVE can be set with any
436       // state but we don't have the information to know if it should be present for any but the
437       // kNative state.
438       jvmti_state |= (JVMTI_THREAD_STATE_IN_NATIVE |
439                       JVMTI_THREAD_STATE_RUNNABLE);
440       break;
441     case art::ThreadState::kBlocked:
442       // Blocked is one of the top level states so it sits alone.
443       jvmti_state |= JVMTI_THREAD_STATE_BLOCKED_ON_MONITOR_ENTER;
444       break;
445     case art::ThreadState::kWaiting:
446       // Object.wait() so waiting, indefinitely, in object.wait.
447       jvmti_state |= (JVMTI_THREAD_STATE_WAITING |
448                       JVMTI_THREAD_STATE_WAITING_INDEFINITELY |
449                       JVMTI_THREAD_STATE_IN_OBJECT_WAIT);
450       break;
451     case art::ThreadState::kTimedWaiting:
452       // Object.wait(long) so waiting, with timeout, in object.wait.
453       jvmti_state |= (JVMTI_THREAD_STATE_WAITING |
454                       JVMTI_THREAD_STATE_WAITING_WITH_TIMEOUT |
455                       JVMTI_THREAD_STATE_IN_OBJECT_WAIT);
456       break;
457     case art::ThreadState::kSleeping:
458       // In object.sleep. This is a timed wait caused by sleep.
459       jvmti_state |= (JVMTI_THREAD_STATE_WAITING |
460                       JVMTI_THREAD_STATE_WAITING_WITH_TIMEOUT |
461                       JVMTI_THREAD_STATE_SLEEPING);
462       break;
463     // TODO We might want to print warnings if we have the debugger running while JVMTI agents are
464     // attached.
465     case art::ThreadState::kWaitingForDebuggerSend:
466     case art::ThreadState::kWaitingForDebuggerToAttach:
467     case art::ThreadState::kWaitingInMainDebuggerLoop:
468     case art::ThreadState::kWaitingForDebuggerSuspension:
469     case art::ThreadState::kWaitingForLockInflation:
470     case art::ThreadState::kWaitingForTaskProcessor:
471     case art::ThreadState::kWaitingForGcToComplete:
472     case art::ThreadState::kWaitingForCheckPointsToRun:
473     case art::ThreadState::kWaitingPerformingGc:
474     case art::ThreadState::kWaitingForJniOnLoad:
475     case art::ThreadState::kWaitingInMainSignalCatcherLoop:
476     case art::ThreadState::kWaitingForSignalCatcherOutput:
477     case art::ThreadState::kWaitingForDeoptimization:
478     case art::ThreadState::kWaitingForMethodTracingStart:
479     case art::ThreadState::kWaitingForVisitObjects:
480     case art::ThreadState::kWaitingForGetObjectsAllocated:
481     case art::ThreadState::kWaitingForGcThreadFlip:
482     case art::ThreadState::kNativeForAbort:
483       // All of these are causing the thread to wait for an indeterminate amount of time but isn't
484       // caused by sleep, park, or object#wait.
485       jvmti_state |= (JVMTI_THREAD_STATE_WAITING |
486                       JVMTI_THREAD_STATE_WAITING_INDEFINITELY);
487       break;
488     case art::ThreadState::kObsoleteRunnable:  // Obsolete value.
489     case art::ThreadState::kStarting:
490     case art::ThreadState::kTerminated:
491     case art::ThreadState::kInvalidState:
492       // We only call this if we are alive so we shouldn't see either of these states.
493       LOG(FATAL) << "Should not be in state " << internal_thread_state;
494       UNREACHABLE();
495   }
496   // TODO: PARKED. We'll have to inspect the stack.
497 
498   return jvmti_state;
499 }
500 
GetJavaStateFromInternal(const InternalThreadState & state)501 static jint GetJavaStateFromInternal(const InternalThreadState& state) {
502   switch (state.art_state) {
503     case art::ThreadState::kTerminated:
504       return JVMTI_JAVA_LANG_THREAD_STATE_TERMINATED;
505 
506     case art::ThreadState::kRunnable:
507     case art::ThreadState::kNative:
508     case art::ThreadState::kWaitingWeakGcRootRead:
509     case art::ThreadState::kSuspended:
510       return JVMTI_JAVA_LANG_THREAD_STATE_RUNNABLE;
511 
512     case art::ThreadState::kTimedWaiting:
513     case art::ThreadState::kSleeping:
514       return JVMTI_JAVA_LANG_THREAD_STATE_TIMED_WAITING;
515 
516     case art::ThreadState::kBlocked:
517       return JVMTI_JAVA_LANG_THREAD_STATE_BLOCKED;
518 
519     case art::ThreadState::kStarting:
520       return JVMTI_JAVA_LANG_THREAD_STATE_NEW;
521 
522     case art::ThreadState::kWaiting:
523     case art::ThreadState::kWaitingForTaskProcessor:
524     case art::ThreadState::kWaitingForLockInflation:
525     case art::ThreadState::kWaitingForGcToComplete:
526     case art::ThreadState::kWaitingPerformingGc:
527     case art::ThreadState::kWaitingForCheckPointsToRun:
528     case art::ThreadState::kWaitingForDebuggerSend:
529     case art::ThreadState::kWaitingForDebuggerToAttach:
530     case art::ThreadState::kWaitingInMainDebuggerLoop:
531     case art::ThreadState::kWaitingForDebuggerSuspension:
532     case art::ThreadState::kWaitingForDeoptimization:
533     case art::ThreadState::kWaitingForGetObjectsAllocated:
534     case art::ThreadState::kWaitingForJniOnLoad:
535     case art::ThreadState::kWaitingForSignalCatcherOutput:
536     case art::ThreadState::kWaitingInMainSignalCatcherLoop:
537     case art::ThreadState::kWaitingForMethodTracingStart:
538     case art::ThreadState::kWaitingForVisitObjects:
539     case art::ThreadState::kWaitingForGcThreadFlip:
540     case art::ThreadState::kNativeForAbort:
541       return JVMTI_JAVA_LANG_THREAD_STATE_WAITING;
542 
543     case art::ThreadState::kObsoleteRunnable:
544     case art::ThreadState::kInvalidState:
545       break;  // Obsolete or invalid value.
546   }
547   LOG(FATAL) << "Unreachable";
548   UNREACHABLE();
549 }
550 
551 // Suspends the current thread if it has any suspend requests on it.
SuspendCheck(art::Thread * self)552 void ThreadUtil::SuspendCheck(art::Thread* self) {
553   DCHECK(!self->ReadFlag(art::ThreadFlag::kSuspensionImmune));
554   art::ScopedObjectAccess soa(self);
555   // Really this is only needed if we are in FastJNI and actually have the mutator_lock_ already.
556   self->FullSuspendCheck();
557 }
558 
WouldSuspendForUserCodeLocked(art::Thread * self)559 bool ThreadUtil::WouldSuspendForUserCodeLocked(art::Thread* self) {
560   DCHECK(self == art::Thread::Current());
561   art::MutexLock tscl_mu(self, *art::Locks::thread_suspend_count_lock_);
562   return self->GetUserCodeSuspendCount() != 0;
563 }
564 
WouldSuspendForUserCode(art::Thread * self)565 bool ThreadUtil::WouldSuspendForUserCode(art::Thread* self) {
566   DCHECK(self == art::Thread::Current());
567   art::MutexLock ucsl_mu(self, *art::Locks::user_code_suspension_lock_);
568   return WouldSuspendForUserCodeLocked(self);
569 }
570 
GetThreadState(jvmtiEnv * env,jthread thread,jint * thread_state_ptr)571 jvmtiError ThreadUtil::GetThreadState([[maybe_unused]] jvmtiEnv* env,
572                                       jthread thread,
573                                       jint* thread_state_ptr) {
574   if (thread_state_ptr == nullptr) {
575     return ERR(NULL_POINTER);
576   }
577 
578   art::Thread* self = art::Thread::Current();
579   InternalThreadState state = {};
580   {
581     ScopedNoUserCodeSuspension snucs(self);
582     art::ScopedObjectAccess soa(self);
583     art::MutexLock tll_mu(self, *art::Locks::thread_list_lock_);
584     jvmtiError err = ERR(INTERNAL);
585     art::Thread* target = nullptr;
586     if (!GetNativeThread(thread, soa, &target, &err)) {
587       return err;
588     }
589     state = GetNativeThreadState(target);
590     if (state.art_state != art::ThreadState::kStarting) {
591       DCHECK(state.native_thread != nullptr);
592 
593       // Translate internal thread state to JVMTI and Java state.
594       jint jvmti_state = GetJvmtiThreadStateFromInternal(state);
595 
596       // Java state is derived from nativeGetState.
597       // TODO: Our implementation assigns "runnable" to suspended. As such, we will have slightly
598       //       different mask if a thread got suspended due to user-code. However, this is for
599       //       consistency with the Java view.
600       jint java_state = GetJavaStateFromInternal(state);
601 
602       *thread_state_ptr = jvmti_state | java_state;
603 
604       return ERR(NONE);
605     }
606   }
607 
608   DCHECK_EQ(state.art_state, art::ThreadState::kStarting);
609 
610   if (thread == nullptr) {
611     // No native thread, and no Java thread? We must be starting up. Report as wrong phase.
612     return ERR(WRONG_PHASE);
613   }
614 
615   art::ScopedObjectAccess soa(self);
616   art::StackHandleScope<1> hs(self);
617 
618   // Need to read the Java "started" field to know whether this is starting or terminated.
619   art::Handle<art::mirror::Object> peer(hs.NewHandle(soa.Decode<art::mirror::Object>(thread)));
620   art::ObjPtr<art::mirror::Class> thread_klass = art::WellKnownClasses::java_lang_Thread.Get();
621   if (!thread_klass->IsAssignableFrom(peer->GetClass())) {
622     return ERR(INVALID_THREAD);
623   }
624   art::ArtField* started_field = thread_klass->FindDeclaredInstanceField("started", "Z");
625   CHECK(started_field != nullptr);
626   bool started = started_field->GetBoolean(peer.Get()) != 0;
627   constexpr jint kStartedState = JVMTI_JAVA_LANG_THREAD_STATE_NEW;
628   constexpr jint kTerminatedState = JVMTI_THREAD_STATE_TERMINATED |
629                                     JVMTI_JAVA_LANG_THREAD_STATE_TERMINATED;
630   *thread_state_ptr = started ? kTerminatedState : kStartedState;
631   return ERR(NONE);
632 }
633 
GetAllThreads(jvmtiEnv * env,jint * threads_count_ptr,jthread ** threads_ptr)634 jvmtiError ThreadUtil::GetAllThreads(jvmtiEnv* env,
635                                      jint* threads_count_ptr,
636                                      jthread** threads_ptr) {
637   if (threads_count_ptr == nullptr || threads_ptr == nullptr) {
638     return ERR(NULL_POINTER);
639   }
640 
641   art::Thread* current = art::Thread::Current();
642 
643   art::ScopedObjectAccess soa(current);
644 
645   art::MutexLock mu(current, *art::Locks::thread_list_lock_);
646   std::list<art::Thread*> thread_list = art::Runtime::Current()->GetThreadList()->GetList();
647   // We have to be careful with threads exiting while we build this list.
648   std::vector<art::ThreadExitFlag> tefs(thread_list.size());
649   auto i = tefs.begin();
650   for (art::Thread* thd : thread_list) {
651     thd->NotifyOnThreadExit(&*i++);
652   }
653   DCHECK(i == tefs.end());
654 
655   std::vector<art::ObjPtr<art::mirror::Object>> peers;
656 
657   i = tefs.begin();
658   for (art::Thread* thread : thread_list) {
659     art::ThreadExitFlag* tef = &*i++;
660     // Skip threads that have since exited or are still starting.
661     if (!tef->HasExited() && !thread->IsStillStarting()) {
662       // LockedGetPeerFromOtherThreads() may release lock!
663       art::ObjPtr<art::mirror::Object> peer = thread->LockedGetPeerFromOtherThread(tef);
664       if (peer != nullptr) {
665         peers.push_back(peer);
666       }
667     }
668     thread->UnregisterThreadExitFlag(tef);
669   }
670   DCHECK(i == tefs.end());
671 
672   if (peers.empty()) {
673     *threads_count_ptr = 0;
674     *threads_ptr = nullptr;
675   } else {
676     unsigned char* data;
677     jvmtiError data_result = env->Allocate(peers.size() * sizeof(jthread), &data);
678     if (data_result != ERR(NONE)) {
679       return data_result;
680     }
681     jthread* threads = reinterpret_cast<jthread*>(data);
682     for (size_t j = 0; j != peers.size(); ++j) {
683       threads[j] = soa.AddLocalReference<jthread>(peers[j]);
684     }
685 
686     *threads_count_ptr = static_cast<jint>(peers.size());
687     *threads_ptr = threads;
688   }
689   return ERR(NONE);
690 }
691 
RemoveTLSData(art::Thread * target,void * ctx)692 static void RemoveTLSData(art::Thread* target, void* ctx) REQUIRES(art::Locks::thread_list_lock_) {
693   jvmtiEnv* env = reinterpret_cast<jvmtiEnv*>(ctx);
694   art::Locks::thread_list_lock_->AssertHeld(art::Thread::Current());
695   JvmtiGlobalTLSData* global_tls = ThreadUtil::GetGlobalTLSData(target);
696   if (global_tls != nullptr) {
697     global_tls->data.erase(env);
698   }
699 }
700 
RemoveEnvironment(jvmtiEnv * env)701 void ThreadUtil::RemoveEnvironment(jvmtiEnv* env) {
702   art::Thread* self = art::Thread::Current();
703   art::MutexLock mu(self, *art::Locks::thread_list_lock_);
704   art::ThreadList* list = art::Runtime::Current()->GetThreadList();
705   list->ForEach(RemoveTLSData, env);
706 }
707 
SetThreadLocalStorage(jvmtiEnv * env,jthread thread,const void * data)708 jvmtiError ThreadUtil::SetThreadLocalStorage(jvmtiEnv* env, jthread thread, const void* data) {
709   art::Thread* self = art::Thread::Current();
710   art::ScopedObjectAccess soa(self);
711   art::MutexLock mu(self, *art::Locks::thread_list_lock_);
712   art::Thread* target = nullptr;
713   jvmtiError err = ERR(INTERNAL);
714   if (!GetAliveNativeThread(thread, soa, &target, &err)) {
715     return err;
716   }
717 
718   JvmtiGlobalTLSData* global_tls = GetOrCreateGlobalTLSData(target);
719 
720   global_tls->data[env] = data;
721 
722   return ERR(NONE);
723 }
724 
GetOrCreateGlobalTLSData(art::Thread * thread)725 JvmtiGlobalTLSData* ThreadUtil::GetOrCreateGlobalTLSData(art::Thread* thread) {
726   JvmtiGlobalTLSData* data = GetGlobalTLSData(thread);
727   if (data != nullptr) {
728     return data;
729   } else {
730     thread->SetCustomTLS(kJvmtiTlsKey, new JvmtiGlobalTLSData);
731     return GetGlobalTLSData(thread);
732   }
733 }
734 
GetGlobalTLSData(art::Thread * thread)735 JvmtiGlobalTLSData* ThreadUtil::GetGlobalTLSData(art::Thread* thread) {
736   return reinterpret_cast<JvmtiGlobalTLSData*>(thread->GetCustomTLS(kJvmtiTlsKey));
737 }
738 
GetThreadLocalStorage(jvmtiEnv * env,jthread thread,void ** data_ptr)739 jvmtiError ThreadUtil::GetThreadLocalStorage(jvmtiEnv* env,
740                                              jthread thread,
741                                              void** data_ptr) {
742   if (data_ptr == nullptr) {
743     return ERR(NULL_POINTER);
744   }
745 
746   art::Thread* self = art::Thread::Current();
747   art::ScopedObjectAccess soa(self);
748   art::MutexLock mu(self, *art::Locks::thread_list_lock_);
749   art::Thread* target = nullptr;
750   jvmtiError err = ERR(INTERNAL);
751   if (!GetAliveNativeThread(thread, soa, &target, &err)) {
752     return err;
753   }
754 
755   JvmtiGlobalTLSData* global_tls = GetGlobalTLSData(target);
756   if (global_tls == nullptr) {
757     *data_ptr = nullptr;
758     return OK;
759   }
760   auto it = global_tls->data.find(env);
761   if (it != global_tls->data.end()) {
762     *data_ptr = const_cast<void*>(it->second);
763   } else {
764     *data_ptr = nullptr;
765   }
766 
767   return ERR(NONE);
768 }
769 
770 struct AgentData {
771   const void* arg;
772   jvmtiStartFunction proc;
773   jthread thread;
774   JavaVM* java_vm;
775   jvmtiEnv* jvmti_env;
776   jint priority;
777   std::string name;
778 };
779 
AgentCallback(void * arg)780 static void* AgentCallback(void* arg) {
781   std::unique_ptr<AgentData> data(reinterpret_cast<AgentData*>(arg));
782   CHECK(data->thread != nullptr);
783 
784   // We already have a peer. So call our special Attach function.
785   art::Thread* self = art::Thread::Attach(data->name.c_str(), true, data->thread);
786   CHECK(self != nullptr) << "threads_being_born_ should have ensured thread could be attached.";
787   // The name in Attach() is only for logging. Set the thread name. This is important so
788   // that the thread is no longer seen as starting up.
789   {
790     art::ScopedObjectAccess soa(self);
791     self->SetThreadName(data->name.c_str());
792   }
793 
794   // Release the peer.
795   JNIEnv* env = self->GetJniEnv();
796   env->DeleteGlobalRef(data->thread);
797   data->thread = nullptr;
798 
799   {
800     // The StartThreadBirth was called in the parent thread. We let the runtime know we are up
801     // before going into the provided code.
802     art::MutexLock mu(art::Thread::Current(), *art::Locks::runtime_shutdown_lock_);
803     art::Runtime::Current()->EndThreadBirth();
804   }
805 
806   // Run the agent code.
807   data->proc(data->jvmti_env, env, const_cast<void*>(data->arg));
808 
809   // Detach the thread.
810   int detach_result = data->java_vm->DetachCurrentThread();
811   CHECK_EQ(detach_result, 0);
812 
813   return nullptr;
814 }
815 
RunAgentThread(jvmtiEnv * jvmti_env,jthread thread,jvmtiStartFunction proc,const void * arg,jint priority)816 jvmtiError ThreadUtil::RunAgentThread(jvmtiEnv* jvmti_env,
817                                       jthread thread,
818                                       jvmtiStartFunction proc,
819                                       const void* arg,
820                                       jint priority) {
821   if (!PhaseUtil::IsLivePhase()) {
822     return ERR(WRONG_PHASE);
823   }
824   if (priority < JVMTI_THREAD_MIN_PRIORITY || priority > JVMTI_THREAD_MAX_PRIORITY) {
825     return ERR(INVALID_PRIORITY);
826   }
827   if (thread == nullptr) {
828     return ERR(INVALID_THREAD);
829   }
830   art::Runtime* runtime = art::Runtime::Current();
831   art::Thread* self = art::Thread::Current();
832   std::unique_ptr<AgentData> data;
833   {
834     art::ScopedObjectAccess soa(self);
835     art::ObjPtr<art::mirror::Object> othread = soa.Decode<art::mirror::Object>(thread);
836     if (!othread->InstanceOf(art::WellKnownClasses::java_lang_Thread.Get())) {
837       return ERR(INVALID_THREAD);
838     }
839     if (proc == nullptr) {
840       return ERR(NULL_POINTER);
841     }
842 
843     {
844       art::MutexLock mu(soa.Self(), *art::Locks::runtime_shutdown_lock_);
845       if (runtime->IsShuttingDownLocked()) {
846         // The runtime is shutting down so we cannot create new threads.
847         // TODO It's not fully clear from the spec what we should do here. We aren't yet in
848         // JVMTI_PHASE_DEAD so we cannot return ERR(WRONG_PHASE) but creating new threads is now
849         // impossible. Existing agents don't seem to generally do anything with this return value so
850         // it doesn't matter too much. We could do something like sending a fake ThreadStart event
851         // even though code is never actually run.
852         return ERR(INTERNAL);
853       }
854       runtime->StartThreadBirth();
855     }
856 
857     data.reset(new AgentData);
858     data->arg = arg;
859     data->proc = proc;
860     // We need a global ref for Java objects, as local refs will be invalid.
861     data->thread = runtime->GetJavaVM()->AddGlobalRef(soa.Self(), othread);
862     data->java_vm = runtime->GetJavaVM();
863     data->jvmti_env = jvmti_env;
864     data->priority = priority;
865     art::ObjPtr<art::mirror::Object> name =
866         art::WellKnownClasses::java_lang_Thread_name->GetObject(
867             soa.Decode<art::mirror::Object>(thread));
868     if (name == nullptr) {
869       data->name = "JVMTI Agent Thread";
870     } else {
871       data->name = name->AsString()->ToModifiedUtf8();
872     }
873   }
874 
875   pthread_t pthread;
876   int pthread_create_result = pthread_create(&pthread,
877                                             nullptr,
878                                             &AgentCallback,
879                                             reinterpret_cast<void*>(data.get()));
880   if (pthread_create_result != 0) {
881     // If the create succeeded the other thread will call EndThreadBirth.
882     art::MutexLock mu(self, *art::Locks::runtime_shutdown_lock_);
883     runtime->EndThreadBirth();
884     return ERR(INTERNAL);
885   }
886   data.release();  // NOLINT pthreads API.
887 
888   return ERR(NONE);
889 }
890 
SuspendOther(art::Thread * self,jthread target_jthread)891 jvmtiError ThreadUtil::SuspendOther(art::Thread* self,
892                                     jthread target_jthread) {
893   // Loop since we need to bail out and try again if we would end up getting suspended while holding
894   // the user_code_suspension_lock_ due to a SuspendReason::kForUserCode. In this situation we
895   // release the lock, wait to get resumed and try again.
896   do {
897     ScopedNoUserCodeSuspension snucs(self);
898     // We are not going to be suspended by user code from now on.
899     {
900       art::ScopedObjectAccess soa(self);
901       art::MutexLock thread_list_mu(self, *art::Locks::thread_list_lock_);
902       art::Thread* target = nullptr;
903       jvmtiError err = ERR(INTERNAL);
904       if (!GetAliveNativeThread(target_jthread, soa, &target, &err)) {
905         return err;
906       }
907       art::ThreadState state = target->GetState();
908       if (state == art::ThreadState::kStarting || target->IsStillStarting()) {
909         return ERR(THREAD_NOT_ALIVE);
910       } else {
911         art::MutexLock thread_suspend_count_mu(self, *art::Locks::thread_suspend_count_lock_);
912         if (target->GetUserCodeSuspendCount() != 0) {
913           return ERR(THREAD_SUSPENDED);
914         }
915       }
916     }
917     art::Thread* ret_target = art::Runtime::Current()->GetThreadList()->SuspendThreadByPeer(
918         target_jthread, art::SuspendReason::kForUserCode);
919     if (ret_target == nullptr) {
920       // TODO It would be good to get more information about why exactly the thread failed to
921       // suspend.
922       return ERR(INTERNAL);
923     } else {
924       return OK;
925     }
926     // We timed out. Just go around and try again.
927   } while (true);
928 }
929 
SuspendSelf(art::Thread * self)930 jvmtiError ThreadUtil::SuspendSelf(art::Thread* self) {
931   CHECK(self == art::Thread::Current());
932   {
933     art::MutexLock mu(self, *art::Locks::user_code_suspension_lock_);
934     art::MutexLock thread_list_mu(self, *art::Locks::thread_suspend_count_lock_);
935     if (self->GetUserCodeSuspendCount() != 0) {
936       // This can only happen if we race with another thread to suspend 'self' and we lose.
937       return ERR(THREAD_SUSPENDED);
938     }
939     {
940       // IncrementSuspendCount normally needs thread_list_lock_ to ensure the thread stays
941       // around. In this case we are the target thread, so we fake it.
942       art::FakeMutexLock fmu(*art::Locks::thread_list_lock_);
943       self->IncrementSuspendCount(self, nullptr, nullptr, art::SuspendReason::kForUserCode);
944     }
945   }
946   // Once we have requested the suspend we actually go to sleep. We need to do this after releasing
947   // the suspend_lock to make sure we can be woken up. This call gains the mutator lock causing us
948   // to go to sleep until we are resumed.
949   SuspendCheck(self);
950   return OK;
951 }
952 
SuspendThread(jvmtiEnv * env,jthread thread)953 jvmtiError ThreadUtil::SuspendThread([[maybe_unused]] jvmtiEnv* env, jthread thread) {
954   art::Thread* self = art::Thread::Current();
955   bool target_is_self = false;
956   {
957     art::ScopedObjectAccess soa(self);
958     art::MutexLock mu(self, *art::Locks::thread_list_lock_);
959     art::Thread* target = nullptr;
960     jvmtiError err = ERR(INTERNAL);
961     if (!GetAliveNativeThread(thread, soa, &target, &err)) {
962       return err;
963     } else if (target == self) {
964       target_is_self = true;
965     }
966   }
967   if (target_is_self) {
968     return SuspendSelf(self);
969   } else {
970     return SuspendOther(self, thread);
971   }
972 }
973 
ResumeThread(jvmtiEnv * env,jthread thread)974 jvmtiError ThreadUtil::ResumeThread([[maybe_unused]] jvmtiEnv* env, jthread thread) {
975   if (thread == nullptr) {
976     return ERR(NULL_POINTER);
977   }
978   art::Thread* self = art::Thread::Current();
979   art::Thread* target;
980 
981   // Make sure we won't get suspended ourselves while in the middle of resuming another thread.
982   ScopedNoUserCodeSuspension snucs(self);
983   // From now on we know we cannot get suspended by user-code.
984   {
985     // NB This does a SuspendCheck (during thread state change) so we need to make sure we don't
986     // have the 'suspend_lock' locked here.
987     art::ScopedObjectAccess soa(self);
988     art::MutexLock tll_mu(self, *art::Locks::thread_list_lock_);
989     jvmtiError err = ERR(INTERNAL);
990     if (!GetAliveNativeThread(thread, soa, &target, &err)) {
991       return err;
992     } else if (target == self) {
993       // We would have paused until we aren't suspended anymore due to the ScopedObjectAccess so
994       // we can just return THREAD_NOT_SUSPENDED. Unfortunately we cannot do any real DCHECKs
995       // about current state since it's all concurrent.
996       return ERR(THREAD_NOT_SUSPENDED);
997     }
998     // The JVMTI spec requires us to return THREAD_NOT_SUSPENDED if it is alive but we really
999     // cannot tell why resume failed.
1000     {
1001       art::MutexLock thread_suspend_count_mu(self, *art::Locks::thread_suspend_count_lock_);
1002       if (target->GetUserCodeSuspendCount() == 0) {
1003         return ERR(THREAD_NOT_SUSPENDED);
1004       }
1005     }
1006   }
1007   // It is okay that we don't have a thread_list_lock here since we know that the thread cannot
1008   // die since it is currently held suspended by a SuspendReason::kForUserCode suspend.
1009   DCHECK(target != self);
1010   if (!art::Runtime::Current()->GetThreadList()->Resume(target,
1011                                                         art::SuspendReason::kForUserCode)) {
1012     // TODO Give a better error.
1013     // This is most likely THREAD_NOT_SUSPENDED but we cannot really be sure.
1014     return ERR(INTERNAL);
1015   } else {
1016     return OK;
1017   }
1018 }
1019 
IsCurrentThread(jthread thr)1020 static bool IsCurrentThread(jthread thr) {
1021   if (thr == nullptr) {
1022     return true;
1023   }
1024   art::Thread* self = art::Thread::Current();
1025   art::ScopedObjectAccess soa(self);
1026   art::MutexLock mu(self, *art::Locks::thread_list_lock_);
1027   art::Thread* target = nullptr;
1028   jvmtiError err_unused = ERR(INTERNAL);
1029   if (ThreadUtil::GetNativeThread(thr, soa, &target, &err_unused)) {
1030     return target == self;
1031   } else {
1032     return false;
1033   }
1034 }
1035 
1036 // Suspends all the threads in the list at the same time. Getting this behavior is a little tricky
1037 // since we can have threads in the list multiple times. This generally doesn't matter unless the
1038 // current thread is present multiple times. In that case we need to suspend only once and either
1039 // return the same error code in all the other slots if it failed or return ERR(THREAD_SUSPENDED) if
1040 // it didn't. We also want to handle the current thread last to make the behavior of the code
1041 // simpler to understand.
SuspendThreadList(jvmtiEnv * env,jint request_count,const jthread * threads,jvmtiError * results)1042 jvmtiError ThreadUtil::SuspendThreadList(jvmtiEnv* env,
1043                                          jint request_count,
1044                                          const jthread* threads,
1045                                          jvmtiError* results) {
1046   if (request_count == 0) {
1047     return ERR(ILLEGAL_ARGUMENT);
1048   } else if (results == nullptr || threads == nullptr) {
1049     return ERR(NULL_POINTER);
1050   }
1051   // This is the list of the indexes in 'threads' and 'results' that correspond to the currently
1052   // running thread. These indexes we need to handle specially since we need to only actually
1053   // suspend a single time.
1054   std::vector<jint> current_thread_indexes;
1055   for (jint i = 0; i < request_count; i++) {
1056     if (IsCurrentThread(threads[i])) {
1057       current_thread_indexes.push_back(i);
1058     } else {
1059       results[i] = env->SuspendThread(threads[i]);
1060     }
1061   }
1062   if (!current_thread_indexes.empty()) {
1063     jint first_current_thread_index = current_thread_indexes[0];
1064     // Suspend self.
1065     jvmtiError res = env->SuspendThread(threads[first_current_thread_index]);
1066     results[first_current_thread_index] = res;
1067     // Fill in the rest of the error values as appropriate.
1068     jvmtiError other_results = (res != OK) ? res : ERR(THREAD_SUSPENDED);
1069     for (auto it = ++current_thread_indexes.begin(); it != current_thread_indexes.end(); ++it) {
1070       results[*it] = other_results;
1071     }
1072   }
1073   return OK;
1074 }
1075 
ResumeThreadList(jvmtiEnv * env,jint request_count,const jthread * threads,jvmtiError * results)1076 jvmtiError ThreadUtil::ResumeThreadList(jvmtiEnv* env,
1077                                         jint request_count,
1078                                         const jthread* threads,
1079                                         jvmtiError* results) {
1080   if (request_count == 0) {
1081     return ERR(ILLEGAL_ARGUMENT);
1082   } else if (results == nullptr || threads == nullptr) {
1083     return ERR(NULL_POINTER);
1084   }
1085   for (jint i = 0; i < request_count; i++) {
1086     results[i] = env->ResumeThread(threads[i]);
1087   }
1088   return OK;
1089 }
1090 
StopThread(jvmtiEnv * env,jthread thread,jobject exception)1091 jvmtiError ThreadUtil::StopThread([[maybe_unused]] jvmtiEnv* env,
1092                                   jthread thread,
1093                                   jobject exception) {
1094   art::Thread* self = art::Thread::Current();
1095   art::ScopedObjectAccess soa(self);
1096   art::StackHandleScope<1> hs(self);
1097   if (exception == nullptr) {
1098     return ERR(INVALID_OBJECT);
1099   }
1100   art::ObjPtr<art::mirror::Object> obj(soa.Decode<art::mirror::Object>(exception));
1101   if (!obj->GetClass()->IsThrowableClass()) {
1102     return ERR(INVALID_OBJECT);
1103   }
1104   art::Handle<art::mirror::Throwable> exc(hs.NewHandle(obj->AsThrowable()));
1105   art::Locks::thread_list_lock_->ExclusiveLock(self);
1106   art::Thread* target = nullptr;
1107   jvmtiError err = ERR(INTERNAL);
1108   if (!GetAliveNativeThread(thread, soa, &target, &err)) {
1109     art::Locks::thread_list_lock_->ExclusiveUnlock(self);
1110     return err;
1111   } else if (target->GetState() == art::ThreadState::kStarting || target->IsStillStarting()) {
1112     art::Locks::thread_list_lock_->ExclusiveUnlock(self);
1113     return ERR(THREAD_NOT_ALIVE);
1114   }
1115   struct StopThreadClosure : public art::Closure {
1116    public:
1117     explicit StopThreadClosure(art::Handle<art::mirror::Throwable> except) : exception_(except) { }
1118 
1119     void Run(art::Thread* me) override REQUIRES_SHARED(art::Locks::mutator_lock_) {
1120       // Make sure the thread is prepared to notice the exception.
1121       DeoptManager::Get()->DeoptimizeThread(me);
1122       me->SetAsyncException(exception_.Get());
1123       // Wake up the thread if it is sleeping.
1124       me->Notify();
1125     }
1126 
1127    private:
1128     art::Handle<art::mirror::Throwable> exception_;
1129   };
1130   StopThreadClosure c(exc);
1131   // RequestSynchronousCheckpoint releases the thread_list_lock_ as a part of its execution.
1132   if (target->RequestSynchronousCheckpoint(&c)) {
1133     return OK;
1134   } else {
1135     // Something went wrong, probably the thread died.
1136     return ERR(THREAD_NOT_ALIVE);
1137   }
1138 }
1139 
InterruptThread(jvmtiEnv * env,jthread thread)1140 jvmtiError ThreadUtil::InterruptThread([[maybe_unused]] jvmtiEnv* env, jthread thread) {
1141   art::Thread* self = art::Thread::Current();
1142   art::ScopedObjectAccess soa(self);
1143   art::MutexLock tll_mu(self, *art::Locks::thread_list_lock_);
1144   art::Thread* target = nullptr;
1145   jvmtiError err = ERR(INTERNAL);
1146   if (!GetAliveNativeThread(thread, soa, &target, &err)) {
1147     return err;
1148   } else if (target->GetState() == art::ThreadState::kStarting || target->IsStillStarting()) {
1149     return ERR(THREAD_NOT_ALIVE);
1150   }
1151   target->Interrupt(self);
1152   return OK;
1153 }
1154 
1155 }  // namespace openjdkjvmti
1156