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