1*795d594fSAndroid Build Coastguard Worker /*
2*795d594fSAndroid Build Coastguard Worker * Copyright (C) 2019 The Android Open Source Project
3*795d594fSAndroid Build Coastguard Worker *
4*795d594fSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
5*795d594fSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
6*795d594fSAndroid Build Coastguard Worker * You may obtain a copy of the License at
7*795d594fSAndroid Build Coastguard Worker *
8*795d594fSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
9*795d594fSAndroid Build Coastguard Worker *
10*795d594fSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
11*795d594fSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
12*795d594fSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*795d594fSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
14*795d594fSAndroid Build Coastguard Worker * limitations under the License.
15*795d594fSAndroid Build Coastguard Worker */
16*795d594fSAndroid Build Coastguard Worker
17*795d594fSAndroid Build Coastguard Worker #include "suspend_event_helper.h"
18*795d594fSAndroid Build Coastguard Worker
19*795d594fSAndroid Build Coastguard Worker #include <inttypes.h>
20*795d594fSAndroid Build Coastguard Worker
21*795d594fSAndroid Build Coastguard Worker #include <cstdio>
22*795d594fSAndroid Build Coastguard Worker #include <memory>
23*795d594fSAndroid Build Coastguard Worker #include <string>
24*795d594fSAndroid Build Coastguard Worker #include <vector>
25*795d594fSAndroid Build Coastguard Worker
26*795d594fSAndroid Build Coastguard Worker #include "android-base/logging.h"
27*795d594fSAndroid Build Coastguard Worker #include "android-base/stringprintf.h"
28*795d594fSAndroid Build Coastguard Worker
29*795d594fSAndroid Build Coastguard Worker #include "jni.h"
30*795d594fSAndroid Build Coastguard Worker #include "jvmti.h"
31*795d594fSAndroid Build Coastguard Worker #include "scoped_local_ref.h"
32*795d594fSAndroid Build Coastguard Worker #include "scoped_utf_chars.h"
33*795d594fSAndroid Build Coastguard Worker
34*795d594fSAndroid Build Coastguard Worker // Test infrastructure
35*795d594fSAndroid Build Coastguard Worker #include "jni_binder.h"
36*795d594fSAndroid Build Coastguard Worker #include "jni_helper.h"
37*795d594fSAndroid Build Coastguard Worker #include "jvmti_helper.h"
38*795d594fSAndroid Build Coastguard Worker #include "test_env.h"
39*795d594fSAndroid Build Coastguard Worker #include "ti_macros.h"
40*795d594fSAndroid Build Coastguard Worker
41*795d594fSAndroid Build Coastguard Worker namespace art {
42*795d594fSAndroid Build Coastguard Worker namespace common_suspend_event {
43*795d594fSAndroid Build Coastguard Worker
44*795d594fSAndroid Build Coastguard Worker struct TestData {
45*795d594fSAndroid Build Coastguard Worker jlocation target_loc;
46*795d594fSAndroid Build Coastguard Worker jmethodID target_method;
47*795d594fSAndroid Build Coastguard Worker jclass target_klass;
48*795d594fSAndroid Build Coastguard Worker jfieldID target_field;
49*795d594fSAndroid Build Coastguard Worker jrawMonitorID notify_monitor;
50*795d594fSAndroid Build Coastguard Worker jint frame_pop_offset;
51*795d594fSAndroid Build Coastguard Worker jmethodID frame_pop_setup_method;
52*795d594fSAndroid Build Coastguard Worker std::vector<std::string> interesting_classes;
53*795d594fSAndroid Build Coastguard Worker bool hit_location;
54*795d594fSAndroid Build Coastguard Worker
TestDataart::common_suspend_event::TestData55*795d594fSAndroid Build Coastguard Worker TestData(jvmtiEnv* jvmti,
56*795d594fSAndroid Build Coastguard Worker JNIEnv* env,
57*795d594fSAndroid Build Coastguard Worker jlocation loc,
58*795d594fSAndroid Build Coastguard Worker jobject meth,
59*795d594fSAndroid Build Coastguard Worker jclass klass,
60*795d594fSAndroid Build Coastguard Worker jobject field,
61*795d594fSAndroid Build Coastguard Worker jobject setup_meth,
62*795d594fSAndroid Build Coastguard Worker jint pop_offset,
63*795d594fSAndroid Build Coastguard Worker const std::vector<std::string>&& interesting)
64*795d594fSAndroid Build Coastguard Worker : target_loc(loc), target_method(meth != nullptr ? env->FromReflectedMethod(meth) : nullptr),
65*795d594fSAndroid Build Coastguard Worker target_klass(reinterpret_cast<jclass>(env->NewGlobalRef(klass))),
66*795d594fSAndroid Build Coastguard Worker target_field(field != nullptr ? env->FromReflectedField(field) : nullptr),
67*795d594fSAndroid Build Coastguard Worker frame_pop_offset(pop_offset),
68*795d594fSAndroid Build Coastguard Worker frame_pop_setup_method(setup_meth != nullptr ? env->FromReflectedMethod(setup_meth)
69*795d594fSAndroid Build Coastguard Worker : nullptr),
70*795d594fSAndroid Build Coastguard Worker interesting_classes(interesting), hit_location(false) {
71*795d594fSAndroid Build Coastguard Worker JvmtiErrorToException(
72*795d594fSAndroid Build Coastguard Worker env, jvmti, jvmti->CreateRawMonitor("SuspendStopMonitor", ¬ify_monitor));
73*795d594fSAndroid Build Coastguard Worker }
74*795d594fSAndroid Build Coastguard Worker
PerformSuspendart::common_suspend_event::TestData75*795d594fSAndroid Build Coastguard Worker void PerformSuspend(jvmtiEnv* jvmti, JNIEnv* env) {
76*795d594fSAndroid Build Coastguard Worker // Wake up the waiting thread.
77*795d594fSAndroid Build Coastguard Worker JvmtiErrorToException(env, jvmti, jvmti->RawMonitorEnter(notify_monitor));
78*795d594fSAndroid Build Coastguard Worker hit_location = true;
79*795d594fSAndroid Build Coastguard Worker JvmtiErrorToException(env, jvmti, jvmti->RawMonitorNotifyAll(notify_monitor));
80*795d594fSAndroid Build Coastguard Worker JvmtiErrorToException(env, jvmti, jvmti->RawMonitorExit(notify_monitor));
81*795d594fSAndroid Build Coastguard Worker // Suspend ourself
82*795d594fSAndroid Build Coastguard Worker jvmti->SuspendThread(nullptr);
83*795d594fSAndroid Build Coastguard Worker }
84*795d594fSAndroid Build Coastguard Worker };
85*795d594fSAndroid Build Coastguard Worker
PerformSuspension(jvmtiEnv * jvmti,JNIEnv * env)86*795d594fSAndroid Build Coastguard Worker void PerformSuspension(jvmtiEnv* jvmti, JNIEnv* env) {
87*795d594fSAndroid Build Coastguard Worker TestData* data;
88*795d594fSAndroid Build Coastguard Worker if (JvmtiErrorToException(
89*795d594fSAndroid Build Coastguard Worker env,
90*795d594fSAndroid Build Coastguard Worker jvmti_env,
91*795d594fSAndroid Build Coastguard Worker jvmti->GetThreadLocalStorage(/* thread */ nullptr, reinterpret_cast<void**>(&data)))) {
92*795d594fSAndroid Build Coastguard Worker return;
93*795d594fSAndroid Build Coastguard Worker }
94*795d594fSAndroid Build Coastguard Worker CHECK(data != nullptr);
95*795d594fSAndroid Build Coastguard Worker data->PerformSuspend(jvmti, env);
96*795d594fSAndroid Build Coastguard Worker }
97*795d594fSAndroid Build Coastguard Worker
98*795d594fSAndroid Build Coastguard Worker void JNICALL
cbSingleStep(jvmtiEnv * jvmti,JNIEnv * env,jthread thr,jmethodID meth,jlocation loc)99*795d594fSAndroid Build Coastguard Worker cbSingleStep(jvmtiEnv* jvmti, JNIEnv* env, jthread thr, jmethodID meth, jlocation loc) {
100*795d594fSAndroid Build Coastguard Worker TestData* data;
101*795d594fSAndroid Build Coastguard Worker if (JvmtiErrorToException(
102*795d594fSAndroid Build Coastguard Worker env, jvmti, jvmti->GetThreadLocalStorage(thr, reinterpret_cast<void**>(&data)))) {
103*795d594fSAndroid Build Coastguard Worker return;
104*795d594fSAndroid Build Coastguard Worker }
105*795d594fSAndroid Build Coastguard Worker CHECK(data != nullptr);
106*795d594fSAndroid Build Coastguard Worker if (meth != data->target_method || loc != data->target_loc) {
107*795d594fSAndroid Build Coastguard Worker return;
108*795d594fSAndroid Build Coastguard Worker }
109*795d594fSAndroid Build Coastguard Worker data->PerformSuspend(jvmti, env);
110*795d594fSAndroid Build Coastguard Worker }
111*795d594fSAndroid Build Coastguard Worker
cbExceptionCatch(jvmtiEnv * jvmti,JNIEnv * env,jthread thr,jmethodID method,jlocation location,jobject exception)112*795d594fSAndroid Build Coastguard Worker void JNICALL cbExceptionCatch(jvmtiEnv* jvmti,
113*795d594fSAndroid Build Coastguard Worker JNIEnv* env,
114*795d594fSAndroid Build Coastguard Worker jthread thr,
115*795d594fSAndroid Build Coastguard Worker jmethodID method,
116*795d594fSAndroid Build Coastguard Worker [[maybe_unused]] jlocation location,
117*795d594fSAndroid Build Coastguard Worker [[maybe_unused]] jobject exception) {
118*795d594fSAndroid Build Coastguard Worker TestData* data;
119*795d594fSAndroid Build Coastguard Worker if (JvmtiErrorToException(
120*795d594fSAndroid Build Coastguard Worker env, jvmti, jvmti->GetThreadLocalStorage(thr, reinterpret_cast<void**>(&data)))) {
121*795d594fSAndroid Build Coastguard Worker return;
122*795d594fSAndroid Build Coastguard Worker }
123*795d594fSAndroid Build Coastguard Worker CHECK(data != nullptr);
124*795d594fSAndroid Build Coastguard Worker if (method != data->target_method) {
125*795d594fSAndroid Build Coastguard Worker return;
126*795d594fSAndroid Build Coastguard Worker }
127*795d594fSAndroid Build Coastguard Worker data->PerformSuspend(jvmti, env);
128*795d594fSAndroid Build Coastguard Worker }
129*795d594fSAndroid Build Coastguard Worker
cbException(jvmtiEnv * jvmti,JNIEnv * env,jthread thr,jmethodID method,jlocation location,jobject exception,jmethodID catch_method,jlocation catch_location)130*795d594fSAndroid Build Coastguard Worker void JNICALL cbException(jvmtiEnv* jvmti,
131*795d594fSAndroid Build Coastguard Worker JNIEnv* env,
132*795d594fSAndroid Build Coastguard Worker jthread thr,
133*795d594fSAndroid Build Coastguard Worker jmethodID method,
134*795d594fSAndroid Build Coastguard Worker [[maybe_unused]] jlocation location,
135*795d594fSAndroid Build Coastguard Worker [[maybe_unused]] jobject exception,
136*795d594fSAndroid Build Coastguard Worker [[maybe_unused]] jmethodID catch_method,
137*795d594fSAndroid Build Coastguard Worker [[maybe_unused]] jlocation catch_location) {
138*795d594fSAndroid Build Coastguard Worker TestData* data;
139*795d594fSAndroid Build Coastguard Worker if (JvmtiErrorToException(
140*795d594fSAndroid Build Coastguard Worker env, jvmti, jvmti->GetThreadLocalStorage(thr, reinterpret_cast<void**>(&data)))) {
141*795d594fSAndroid Build Coastguard Worker return;
142*795d594fSAndroid Build Coastguard Worker }
143*795d594fSAndroid Build Coastguard Worker CHECK(data != nullptr);
144*795d594fSAndroid Build Coastguard Worker if (method != data->target_method) {
145*795d594fSAndroid Build Coastguard Worker return;
146*795d594fSAndroid Build Coastguard Worker }
147*795d594fSAndroid Build Coastguard Worker data->PerformSuspend(jvmti, env);
148*795d594fSAndroid Build Coastguard Worker }
149*795d594fSAndroid Build Coastguard Worker
cbMethodEntry(jvmtiEnv * jvmti,JNIEnv * env,jthread thr,jmethodID method)150*795d594fSAndroid Build Coastguard Worker void JNICALL cbMethodEntry(jvmtiEnv* jvmti, JNIEnv* env, jthread thr, jmethodID method) {
151*795d594fSAndroid Build Coastguard Worker TestData* data;
152*795d594fSAndroid Build Coastguard Worker if (JvmtiErrorToException(
153*795d594fSAndroid Build Coastguard Worker env, jvmti, jvmti->GetThreadLocalStorage(thr, reinterpret_cast<void**>(&data)))) {
154*795d594fSAndroid Build Coastguard Worker return;
155*795d594fSAndroid Build Coastguard Worker }
156*795d594fSAndroid Build Coastguard Worker CHECK(data != nullptr);
157*795d594fSAndroid Build Coastguard Worker if (method != data->target_method) {
158*795d594fSAndroid Build Coastguard Worker return;
159*795d594fSAndroid Build Coastguard Worker }
160*795d594fSAndroid Build Coastguard Worker data->PerformSuspend(jvmti, env);
161*795d594fSAndroid Build Coastguard Worker }
162*795d594fSAndroid Build Coastguard Worker
cbMethodExit(jvmtiEnv * jvmti,JNIEnv * env,jthread thr,jmethodID method,jboolean was_popped_by_exception,jvalue return_value)163*795d594fSAndroid Build Coastguard Worker void JNICALL cbMethodExit(jvmtiEnv* jvmti,
164*795d594fSAndroid Build Coastguard Worker JNIEnv* env,
165*795d594fSAndroid Build Coastguard Worker jthread thr,
166*795d594fSAndroid Build Coastguard Worker jmethodID method,
167*795d594fSAndroid Build Coastguard Worker [[maybe_unused]] jboolean was_popped_by_exception,
168*795d594fSAndroid Build Coastguard Worker [[maybe_unused]] jvalue return_value) {
169*795d594fSAndroid Build Coastguard Worker TestData* data;
170*795d594fSAndroid Build Coastguard Worker if (JvmtiErrorToException(
171*795d594fSAndroid Build Coastguard Worker env, jvmti, jvmti->GetThreadLocalStorage(thr, reinterpret_cast<void**>(&data)))) {
172*795d594fSAndroid Build Coastguard Worker return;
173*795d594fSAndroid Build Coastguard Worker }
174*795d594fSAndroid Build Coastguard Worker CHECK(data != nullptr);
175*795d594fSAndroid Build Coastguard Worker if (method != data->target_method) {
176*795d594fSAndroid Build Coastguard Worker return;
177*795d594fSAndroid Build Coastguard Worker }
178*795d594fSAndroid Build Coastguard Worker data->PerformSuspend(jvmti, env);
179*795d594fSAndroid Build Coastguard Worker }
180*795d594fSAndroid Build Coastguard Worker
cbFieldModification(jvmtiEnv * jvmti,JNIEnv * env,jthread thr,jmethodID method,jlocation location,jclass field_klass,jobject object,jfieldID field,char signature_type,jvalue new_value)181*795d594fSAndroid Build Coastguard Worker void JNICALL cbFieldModification(jvmtiEnv* jvmti,
182*795d594fSAndroid Build Coastguard Worker JNIEnv* env,
183*795d594fSAndroid Build Coastguard Worker jthread thr,
184*795d594fSAndroid Build Coastguard Worker [[maybe_unused]] jmethodID method,
185*795d594fSAndroid Build Coastguard Worker [[maybe_unused]] jlocation location,
186*795d594fSAndroid Build Coastguard Worker [[maybe_unused]] jclass field_klass,
187*795d594fSAndroid Build Coastguard Worker [[maybe_unused]] jobject object,
188*795d594fSAndroid Build Coastguard Worker jfieldID field,
189*795d594fSAndroid Build Coastguard Worker [[maybe_unused]] char signature_type,
190*795d594fSAndroid Build Coastguard Worker [[maybe_unused]] jvalue new_value) {
191*795d594fSAndroid Build Coastguard Worker TestData* data;
192*795d594fSAndroid Build Coastguard Worker if (JvmtiErrorToException(
193*795d594fSAndroid Build Coastguard Worker env, jvmti, jvmti->GetThreadLocalStorage(thr, reinterpret_cast<void**>(&data)))) {
194*795d594fSAndroid Build Coastguard Worker return;
195*795d594fSAndroid Build Coastguard Worker }
196*795d594fSAndroid Build Coastguard Worker CHECK(data != nullptr);
197*795d594fSAndroid Build Coastguard Worker if (field != data->target_field) {
198*795d594fSAndroid Build Coastguard Worker // TODO What to do here.
199*795d594fSAndroid Build Coastguard Worker LOG(FATAL) << "Strange, shouldn't get here!";
200*795d594fSAndroid Build Coastguard Worker }
201*795d594fSAndroid Build Coastguard Worker data->PerformSuspend(jvmti, env);
202*795d594fSAndroid Build Coastguard Worker }
203*795d594fSAndroid Build Coastguard Worker
cbFieldAccess(jvmtiEnv * jvmti,JNIEnv * env,jthread thr,jmethodID method,jlocation location,jclass field_klass,jobject object,jfieldID field)204*795d594fSAndroid Build Coastguard Worker void JNICALL cbFieldAccess(jvmtiEnv* jvmti,
205*795d594fSAndroid Build Coastguard Worker JNIEnv* env,
206*795d594fSAndroid Build Coastguard Worker jthread thr,
207*795d594fSAndroid Build Coastguard Worker [[maybe_unused]] jmethodID method,
208*795d594fSAndroid Build Coastguard Worker [[maybe_unused]] jlocation location,
209*795d594fSAndroid Build Coastguard Worker jclass field_klass,
210*795d594fSAndroid Build Coastguard Worker [[maybe_unused]] jobject object,
211*795d594fSAndroid Build Coastguard Worker jfieldID field) {
212*795d594fSAndroid Build Coastguard Worker TestData* data;
213*795d594fSAndroid Build Coastguard Worker if (JvmtiErrorToException(
214*795d594fSAndroid Build Coastguard Worker env, jvmti, jvmti->GetThreadLocalStorage(thr, reinterpret_cast<void**>(&data)))) {
215*795d594fSAndroid Build Coastguard Worker return;
216*795d594fSAndroid Build Coastguard Worker }
217*795d594fSAndroid Build Coastguard Worker CHECK(data != nullptr);
218*795d594fSAndroid Build Coastguard Worker if (field != data->target_field || !env->IsSameObject(field_klass, data->target_klass)) {
219*795d594fSAndroid Build Coastguard Worker // TODO What to do here.
220*795d594fSAndroid Build Coastguard Worker LOG(FATAL) << "Strange, shouldn't get here!";
221*795d594fSAndroid Build Coastguard Worker }
222*795d594fSAndroid Build Coastguard Worker data->PerformSuspend(jvmti, env);
223*795d594fSAndroid Build Coastguard Worker }
224*795d594fSAndroid Build Coastguard Worker
225*795d594fSAndroid Build Coastguard Worker void JNICALL
cbBreakpointHit(jvmtiEnv * jvmti,JNIEnv * env,jthread thr,jmethodID method,jlocation loc)226*795d594fSAndroid Build Coastguard Worker cbBreakpointHit(jvmtiEnv* jvmti, JNIEnv* env, jthread thr, jmethodID method, jlocation loc) {
227*795d594fSAndroid Build Coastguard Worker TestData* data;
228*795d594fSAndroid Build Coastguard Worker if (JvmtiErrorToException(
229*795d594fSAndroid Build Coastguard Worker env, jvmti, jvmti->GetThreadLocalStorage(thr, reinterpret_cast<void**>(&data)))) {
230*795d594fSAndroid Build Coastguard Worker return;
231*795d594fSAndroid Build Coastguard Worker }
232*795d594fSAndroid Build Coastguard Worker CHECK(data != nullptr);
233*795d594fSAndroid Build Coastguard Worker if (data->frame_pop_setup_method == method) {
234*795d594fSAndroid Build Coastguard Worker CHECK(loc == 0) << "We should have stopped at location 0";
235*795d594fSAndroid Build Coastguard Worker if (JvmtiErrorToException(env, jvmti, jvmti->NotifyFramePop(thr, data->frame_pop_offset))) {
236*795d594fSAndroid Build Coastguard Worker return;
237*795d594fSAndroid Build Coastguard Worker }
238*795d594fSAndroid Build Coastguard Worker return;
239*795d594fSAndroid Build Coastguard Worker }
240*795d594fSAndroid Build Coastguard Worker if (method != data->target_method || loc != data->target_loc) {
241*795d594fSAndroid Build Coastguard Worker // TODO What to do here.
242*795d594fSAndroid Build Coastguard Worker LOG(FATAL) << "Strange, shouldn't get here!";
243*795d594fSAndroid Build Coastguard Worker }
244*795d594fSAndroid Build Coastguard Worker data->PerformSuspend(jvmti, env);
245*795d594fSAndroid Build Coastguard Worker }
246*795d594fSAndroid Build Coastguard Worker
cbFramePop(jvmtiEnv * jvmti,JNIEnv * env,jthread thr,jmethodID method,jboolean was_popped_by_exception)247*795d594fSAndroid Build Coastguard Worker void JNICALL cbFramePop(jvmtiEnv* jvmti,
248*795d594fSAndroid Build Coastguard Worker JNIEnv* env,
249*795d594fSAndroid Build Coastguard Worker jthread thr,
250*795d594fSAndroid Build Coastguard Worker [[maybe_unused]] jmethodID method,
251*795d594fSAndroid Build Coastguard Worker [[maybe_unused]] jboolean was_popped_by_exception) {
252*795d594fSAndroid Build Coastguard Worker TestData* data;
253*795d594fSAndroid Build Coastguard Worker if (JvmtiErrorToException(
254*795d594fSAndroid Build Coastguard Worker env, jvmti, jvmti->GetThreadLocalStorage(thr, reinterpret_cast<void**>(&data)))) {
255*795d594fSAndroid Build Coastguard Worker return;
256*795d594fSAndroid Build Coastguard Worker }
257*795d594fSAndroid Build Coastguard Worker CHECK(data != nullptr);
258*795d594fSAndroid Build Coastguard Worker data->PerformSuspend(jvmti, env);
259*795d594fSAndroid Build Coastguard Worker }
260*795d594fSAndroid Build Coastguard Worker
cbClassLoadOrPrepare(jvmtiEnv * jvmti,JNIEnv * env,jthread thr,jclass klass)261*795d594fSAndroid Build Coastguard Worker void JNICALL cbClassLoadOrPrepare(jvmtiEnv* jvmti, JNIEnv* env, jthread thr, jclass klass) {
262*795d594fSAndroid Build Coastguard Worker TestData* data;
263*795d594fSAndroid Build Coastguard Worker if (JvmtiErrorToException(
264*795d594fSAndroid Build Coastguard Worker env, jvmti, jvmti->GetThreadLocalStorage(thr, reinterpret_cast<void**>(&data)))) {
265*795d594fSAndroid Build Coastguard Worker return;
266*795d594fSAndroid Build Coastguard Worker }
267*795d594fSAndroid Build Coastguard Worker CHECK(data != nullptr);
268*795d594fSAndroid Build Coastguard Worker char* name;
269*795d594fSAndroid Build Coastguard Worker if (JvmtiErrorToException(env, jvmti, jvmti->GetClassSignature(klass, &name, nullptr))) {
270*795d594fSAndroid Build Coastguard Worker return;
271*795d594fSAndroid Build Coastguard Worker }
272*795d594fSAndroid Build Coastguard Worker std::string name_str(name);
273*795d594fSAndroid Build Coastguard Worker if (JvmtiErrorToException(
274*795d594fSAndroid Build Coastguard Worker env, jvmti, jvmti->Deallocate(reinterpret_cast<unsigned char*>(name)))) {
275*795d594fSAndroid Build Coastguard Worker return;
276*795d594fSAndroid Build Coastguard Worker }
277*795d594fSAndroid Build Coastguard Worker if (std::find(data->interesting_classes.cbegin(), data->interesting_classes.cend(), name_str) !=
278*795d594fSAndroid Build Coastguard Worker data->interesting_classes.cend()) {
279*795d594fSAndroid Build Coastguard Worker data->PerformSuspend(jvmti, env);
280*795d594fSAndroid Build Coastguard Worker }
281*795d594fSAndroid Build Coastguard Worker }
282*795d594fSAndroid Build Coastguard Worker
Java_art_SuspendEvents_setupTest(JNIEnv * env,jclass klass)283*795d594fSAndroid Build Coastguard Worker extern "C" JNIEXPORT void JNICALL Java_art_SuspendEvents_setupTest(JNIEnv* env,
284*795d594fSAndroid Build Coastguard Worker [[maybe_unused]] jclass klass) {
285*795d594fSAndroid Build Coastguard Worker jvmtiCapabilities caps;
286*795d594fSAndroid Build Coastguard Worker memset(&caps, 0, sizeof(caps));
287*795d594fSAndroid Build Coastguard Worker // Most of these will already be there but might as well be complete.
288*795d594fSAndroid Build Coastguard Worker caps.can_pop_frame = 1;
289*795d594fSAndroid Build Coastguard Worker caps.can_force_early_return = 1;
290*795d594fSAndroid Build Coastguard Worker caps.can_generate_single_step_events = 1;
291*795d594fSAndroid Build Coastguard Worker caps.can_generate_breakpoint_events = 1;
292*795d594fSAndroid Build Coastguard Worker caps.can_suspend = 1;
293*795d594fSAndroid Build Coastguard Worker caps.can_generate_method_entry_events = 1;
294*795d594fSAndroid Build Coastguard Worker caps.can_generate_method_exit_events = 1;
295*795d594fSAndroid Build Coastguard Worker caps.can_generate_monitor_events = 1;
296*795d594fSAndroid Build Coastguard Worker caps.can_generate_exception_events = 1;
297*795d594fSAndroid Build Coastguard Worker caps.can_generate_frame_pop_events = 1;
298*795d594fSAndroid Build Coastguard Worker caps.can_generate_field_access_events = 1;
299*795d594fSAndroid Build Coastguard Worker caps.can_generate_field_modification_events = 1;
300*795d594fSAndroid Build Coastguard Worker caps.can_redefine_classes = 1;
301*795d594fSAndroid Build Coastguard Worker if (JvmtiErrorToException(env, jvmti_env, jvmti_env->AddCapabilities(&caps))) {
302*795d594fSAndroid Build Coastguard Worker return;
303*795d594fSAndroid Build Coastguard Worker }
304*795d594fSAndroid Build Coastguard Worker jvmtiEventCallbacks cb;
305*795d594fSAndroid Build Coastguard Worker memset(&cb, 0, sizeof(cb));
306*795d594fSAndroid Build Coastguard Worker // TODO Add the rest of these.
307*795d594fSAndroid Build Coastguard Worker cb.Breakpoint = cbBreakpointHit;
308*795d594fSAndroid Build Coastguard Worker cb.SingleStep = cbSingleStep;
309*795d594fSAndroid Build Coastguard Worker cb.FieldAccess = cbFieldAccess;
310*795d594fSAndroid Build Coastguard Worker cb.FieldModification = cbFieldModification;
311*795d594fSAndroid Build Coastguard Worker cb.MethodEntry = cbMethodEntry;
312*795d594fSAndroid Build Coastguard Worker cb.MethodExit = cbMethodExit;
313*795d594fSAndroid Build Coastguard Worker cb.Exception = cbException;
314*795d594fSAndroid Build Coastguard Worker cb.ExceptionCatch = cbExceptionCatch;
315*795d594fSAndroid Build Coastguard Worker cb.FramePop = cbFramePop;
316*795d594fSAndroid Build Coastguard Worker cb.ClassLoad = cbClassLoadOrPrepare;
317*795d594fSAndroid Build Coastguard Worker cb.ClassPrepare = cbClassLoadOrPrepare;
318*795d594fSAndroid Build Coastguard Worker JvmtiErrorToException(env, jvmti_env, jvmti_env->SetEventCallbacks(&cb, sizeof(cb)));
319*795d594fSAndroid Build Coastguard Worker }
320*795d594fSAndroid Build Coastguard Worker
DeleteTestData(JNIEnv * env,jthread thr,TestData * data)321*795d594fSAndroid Build Coastguard Worker static bool DeleteTestData(JNIEnv* env, jthread thr, TestData* data) {
322*795d594fSAndroid Build Coastguard Worker env->DeleteGlobalRef(data->target_klass);
323*795d594fSAndroid Build Coastguard Worker if (JvmtiErrorToException(env, jvmti_env, jvmti_env->SetThreadLocalStorage(thr, nullptr))) {
324*795d594fSAndroid Build Coastguard Worker return false;
325*795d594fSAndroid Build Coastguard Worker }
326*795d594fSAndroid Build Coastguard Worker return JvmtiErrorToException(
327*795d594fSAndroid Build Coastguard Worker env, jvmti_env, jvmti_env->Deallocate(reinterpret_cast<uint8_t*>(data)));
328*795d594fSAndroid Build Coastguard Worker }
329*795d594fSAndroid Build Coastguard Worker
SetupTestData(JNIEnv * env,jobject meth,jlocation loc,jclass target_klass,jobject field,jobject setup_meth,jint pop_offset,const std::vector<std::string> && interesting_names)330*795d594fSAndroid Build Coastguard Worker static TestData* SetupTestData(JNIEnv* env,
331*795d594fSAndroid Build Coastguard Worker jobject meth,
332*795d594fSAndroid Build Coastguard Worker jlocation loc,
333*795d594fSAndroid Build Coastguard Worker jclass target_klass,
334*795d594fSAndroid Build Coastguard Worker jobject field,
335*795d594fSAndroid Build Coastguard Worker jobject setup_meth,
336*795d594fSAndroid Build Coastguard Worker jint pop_offset,
337*795d594fSAndroid Build Coastguard Worker const std::vector<std::string>&& interesting_names) {
338*795d594fSAndroid Build Coastguard Worker void* data_ptr;
339*795d594fSAndroid Build Coastguard Worker TestData* data;
340*795d594fSAndroid Build Coastguard Worker if (JvmtiErrorToException(
341*795d594fSAndroid Build Coastguard Worker env,
342*795d594fSAndroid Build Coastguard Worker jvmti_env,
343*795d594fSAndroid Build Coastguard Worker jvmti_env->Allocate(sizeof(TestData), reinterpret_cast<uint8_t**>(&data_ptr)))) {
344*795d594fSAndroid Build Coastguard Worker return nullptr;
345*795d594fSAndroid Build Coastguard Worker }
346*795d594fSAndroid Build Coastguard Worker data = new (data_ptr) TestData(jvmti_env,
347*795d594fSAndroid Build Coastguard Worker env,
348*795d594fSAndroid Build Coastguard Worker loc,
349*795d594fSAndroid Build Coastguard Worker meth,
350*795d594fSAndroid Build Coastguard Worker target_klass,
351*795d594fSAndroid Build Coastguard Worker field,
352*795d594fSAndroid Build Coastguard Worker setup_meth,
353*795d594fSAndroid Build Coastguard Worker pop_offset,
354*795d594fSAndroid Build Coastguard Worker std::move(interesting_names));
355*795d594fSAndroid Build Coastguard Worker if (env->ExceptionCheck()) {
356*795d594fSAndroid Build Coastguard Worker env->DeleteGlobalRef(data->target_klass);
357*795d594fSAndroid Build Coastguard Worker jvmti_env->Deallocate(reinterpret_cast<uint8_t*>(data));
358*795d594fSAndroid Build Coastguard Worker return nullptr;
359*795d594fSAndroid Build Coastguard Worker }
360*795d594fSAndroid Build Coastguard Worker return data;
361*795d594fSAndroid Build Coastguard Worker }
362*795d594fSAndroid Build Coastguard Worker
SetupTestData(JNIEnv * env,jobject meth,jlocation loc,jclass target_klass,jobject field,jobject setup_meth,jint pop_offset)363*795d594fSAndroid Build Coastguard Worker static TestData* SetupTestData(JNIEnv* env,
364*795d594fSAndroid Build Coastguard Worker jobject meth,
365*795d594fSAndroid Build Coastguard Worker jlocation loc,
366*795d594fSAndroid Build Coastguard Worker jclass target_klass,
367*795d594fSAndroid Build Coastguard Worker jobject field,
368*795d594fSAndroid Build Coastguard Worker jobject setup_meth,
369*795d594fSAndroid Build Coastguard Worker jint pop_offset) {
370*795d594fSAndroid Build Coastguard Worker std::vector<std::string> empty;
371*795d594fSAndroid Build Coastguard Worker return SetupTestData(
372*795d594fSAndroid Build Coastguard Worker env, meth, loc, target_klass, field, setup_meth, pop_offset, std::move(empty));
373*795d594fSAndroid Build Coastguard Worker }
374*795d594fSAndroid Build Coastguard Worker
375*795d594fSAndroid Build Coastguard Worker extern "C" JNIEXPORT void JNICALL
Java_art_SuspendEvents_setupSuspendClassEvent(JNIEnv * env,jclass klass,jint event_num,jobjectArray interesting_names,jthread thr)376*795d594fSAndroid Build Coastguard Worker Java_art_SuspendEvents_setupSuspendClassEvent(JNIEnv* env,
377*795d594fSAndroid Build Coastguard Worker [[maybe_unused]] jclass klass,
378*795d594fSAndroid Build Coastguard Worker jint event_num,
379*795d594fSAndroid Build Coastguard Worker jobjectArray interesting_names,
380*795d594fSAndroid Build Coastguard Worker jthread thr) {
381*795d594fSAndroid Build Coastguard Worker CHECK(event_num == JVMTI_EVENT_CLASS_LOAD || event_num == JVMTI_EVENT_CLASS_PREPARE);
382*795d594fSAndroid Build Coastguard Worker std::vector<std::string> names;
383*795d594fSAndroid Build Coastguard Worker jint cnt = env->GetArrayLength(interesting_names);
384*795d594fSAndroid Build Coastguard Worker for (jint i = 0; i < cnt; i++) {
385*795d594fSAndroid Build Coastguard Worker env->PushLocalFrame(1);
386*795d594fSAndroid Build Coastguard Worker jstring name_obj = reinterpret_cast<jstring>(env->GetObjectArrayElement(interesting_names, i));
387*795d594fSAndroid Build Coastguard Worker const char* name_chr = env->GetStringUTFChars(name_obj, nullptr);
388*795d594fSAndroid Build Coastguard Worker names.push_back(std::string(name_chr));
389*795d594fSAndroid Build Coastguard Worker env->ReleaseStringUTFChars(name_obj, name_chr);
390*795d594fSAndroid Build Coastguard Worker env->PopLocalFrame(nullptr);
391*795d594fSAndroid Build Coastguard Worker }
392*795d594fSAndroid Build Coastguard Worker TestData* data;
393*795d594fSAndroid Build Coastguard Worker if (JvmtiErrorToException(
394*795d594fSAndroid Build Coastguard Worker env, jvmti_env, jvmti_env->GetThreadLocalStorage(thr, reinterpret_cast<void**>(&data)))) {
395*795d594fSAndroid Build Coastguard Worker return;
396*795d594fSAndroid Build Coastguard Worker }
397*795d594fSAndroid Build Coastguard Worker CHECK(data == nullptr) << "Data was not cleared!";
398*795d594fSAndroid Build Coastguard Worker data = SetupTestData(env, nullptr, 0, nullptr, nullptr, nullptr, 0, std::move(names));
399*795d594fSAndroid Build Coastguard Worker if (data == nullptr) {
400*795d594fSAndroid Build Coastguard Worker return;
401*795d594fSAndroid Build Coastguard Worker }
402*795d594fSAndroid Build Coastguard Worker if (JvmtiErrorToException(env, jvmti_env, jvmti_env->SetThreadLocalStorage(thr, data))) {
403*795d594fSAndroid Build Coastguard Worker return;
404*795d594fSAndroid Build Coastguard Worker }
405*795d594fSAndroid Build Coastguard Worker JvmtiErrorToException(
406*795d594fSAndroid Build Coastguard Worker env,
407*795d594fSAndroid Build Coastguard Worker jvmti_env,
408*795d594fSAndroid Build Coastguard Worker jvmti_env->SetEventNotificationMode(JVMTI_ENABLE, static_cast<jvmtiEvent>(event_num), thr));
409*795d594fSAndroid Build Coastguard Worker }
410*795d594fSAndroid Build Coastguard Worker
Java_art_SuspendEvents_clearSuspendClassEvent(JNIEnv * env,jclass klass,jthread thr)411*795d594fSAndroid Build Coastguard Worker extern "C" JNIEXPORT void JNICALL Java_art_SuspendEvents_clearSuspendClassEvent(
412*795d594fSAndroid Build Coastguard Worker JNIEnv* env, [[maybe_unused]] jclass klass, jthread thr) {
413*795d594fSAndroid Build Coastguard Worker TestData* data;
414*795d594fSAndroid Build Coastguard Worker if (JvmtiErrorToException(
415*795d594fSAndroid Build Coastguard Worker env, jvmti_env, jvmti_env->GetThreadLocalStorage(thr, reinterpret_cast<void**>(&data)))) {
416*795d594fSAndroid Build Coastguard Worker return;
417*795d594fSAndroid Build Coastguard Worker }
418*795d594fSAndroid Build Coastguard Worker CHECK(data != nullptr);
419*795d594fSAndroid Build Coastguard Worker if (JvmtiErrorToException(
420*795d594fSAndroid Build Coastguard Worker env,
421*795d594fSAndroid Build Coastguard Worker jvmti_env,
422*795d594fSAndroid Build Coastguard Worker jvmti_env->SetEventNotificationMode(JVMTI_DISABLE, JVMTI_EVENT_CLASS_LOAD, thr))) {
423*795d594fSAndroid Build Coastguard Worker return;
424*795d594fSAndroid Build Coastguard Worker }
425*795d594fSAndroid Build Coastguard Worker if (JvmtiErrorToException(
426*795d594fSAndroid Build Coastguard Worker env,
427*795d594fSAndroid Build Coastguard Worker jvmti_env,
428*795d594fSAndroid Build Coastguard Worker jvmti_env->SetEventNotificationMode(JVMTI_DISABLE, JVMTI_EVENT_CLASS_PREPARE, thr))) {
429*795d594fSAndroid Build Coastguard Worker return;
430*795d594fSAndroid Build Coastguard Worker }
431*795d594fSAndroid Build Coastguard Worker DeleteTestData(env, thr, data);
432*795d594fSAndroid Build Coastguard Worker }
433*795d594fSAndroid Build Coastguard Worker
Java_art_SuspendEvents_setupSuspendSingleStepAt(JNIEnv * env,jclass klass,jobject meth,jlocation loc,jthread thr)434*795d594fSAndroid Build Coastguard Worker extern "C" JNIEXPORT void JNICALL Java_art_SuspendEvents_setupSuspendSingleStepAt(
435*795d594fSAndroid Build Coastguard Worker JNIEnv* env, [[maybe_unused]] jclass klass, jobject meth, jlocation loc, jthread thr) {
436*795d594fSAndroid Build Coastguard Worker TestData* data;
437*795d594fSAndroid Build Coastguard Worker if (JvmtiErrorToException(
438*795d594fSAndroid Build Coastguard Worker env, jvmti_env, jvmti_env->GetThreadLocalStorage(thr, reinterpret_cast<void**>(&data)))) {
439*795d594fSAndroid Build Coastguard Worker return;
440*795d594fSAndroid Build Coastguard Worker }
441*795d594fSAndroid Build Coastguard Worker CHECK(data == nullptr) << "Data was not cleared!";
442*795d594fSAndroid Build Coastguard Worker data = SetupTestData(env, meth, loc, nullptr, nullptr, nullptr, 0);
443*795d594fSAndroid Build Coastguard Worker if (data == nullptr) {
444*795d594fSAndroid Build Coastguard Worker return;
445*795d594fSAndroid Build Coastguard Worker }
446*795d594fSAndroid Build Coastguard Worker if (JvmtiErrorToException(env, jvmti_env, jvmti_env->SetThreadLocalStorage(thr, data))) {
447*795d594fSAndroid Build Coastguard Worker return;
448*795d594fSAndroid Build Coastguard Worker }
449*795d594fSAndroid Build Coastguard Worker JvmtiErrorToException(
450*795d594fSAndroid Build Coastguard Worker env,
451*795d594fSAndroid Build Coastguard Worker jvmti_env,
452*795d594fSAndroid Build Coastguard Worker jvmti_env->SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_SINGLE_STEP, thr));
453*795d594fSAndroid Build Coastguard Worker }
454*795d594fSAndroid Build Coastguard Worker
Java_art_SuspendEvents_clearSuspendSingleStepFor(JNIEnv * env,jclass klass,jthread thr)455*795d594fSAndroid Build Coastguard Worker extern "C" JNIEXPORT void JNICALL Java_art_SuspendEvents_clearSuspendSingleStepFor(
456*795d594fSAndroid Build Coastguard Worker JNIEnv* env, [[maybe_unused]] jclass klass, jthread thr) {
457*795d594fSAndroid Build Coastguard Worker TestData* data;
458*795d594fSAndroid Build Coastguard Worker if (JvmtiErrorToException(
459*795d594fSAndroid Build Coastguard Worker env, jvmti_env, jvmti_env->GetThreadLocalStorage(thr, reinterpret_cast<void**>(&data)))) {
460*795d594fSAndroid Build Coastguard Worker return;
461*795d594fSAndroid Build Coastguard Worker }
462*795d594fSAndroid Build Coastguard Worker CHECK(data != nullptr);
463*795d594fSAndroid Build Coastguard Worker if (JvmtiErrorToException(
464*795d594fSAndroid Build Coastguard Worker env,
465*795d594fSAndroid Build Coastguard Worker jvmti_env,
466*795d594fSAndroid Build Coastguard Worker jvmti_env->SetEventNotificationMode(JVMTI_DISABLE, JVMTI_EVENT_SINGLE_STEP, thr))) {
467*795d594fSAndroid Build Coastguard Worker return;
468*795d594fSAndroid Build Coastguard Worker }
469*795d594fSAndroid Build Coastguard Worker DeleteTestData(env, thr, data);
470*795d594fSAndroid Build Coastguard Worker }
471*795d594fSAndroid Build Coastguard Worker
Java_art_SuspendEvents_setupSuspendPopFrameEvent(JNIEnv * env,jclass klass,jint offset,jobject breakpoint_func,jthread thr)472*795d594fSAndroid Build Coastguard Worker extern "C" JNIEXPORT void JNICALL Java_art_SuspendEvents_setupSuspendPopFrameEvent(
473*795d594fSAndroid Build Coastguard Worker JNIEnv* env, [[maybe_unused]] jclass klass, jint offset, jobject breakpoint_func, jthread thr) {
474*795d594fSAndroid Build Coastguard Worker TestData* data;
475*795d594fSAndroid Build Coastguard Worker if (JvmtiErrorToException(
476*795d594fSAndroid Build Coastguard Worker env, jvmti_env, jvmti_env->GetThreadLocalStorage(thr, reinterpret_cast<void**>(&data)))) {
477*795d594fSAndroid Build Coastguard Worker return;
478*795d594fSAndroid Build Coastguard Worker }
479*795d594fSAndroid Build Coastguard Worker CHECK(data == nullptr) << "Data was not cleared!";
480*795d594fSAndroid Build Coastguard Worker data = SetupTestData(env, nullptr, 0, nullptr, nullptr, breakpoint_func, offset);
481*795d594fSAndroid Build Coastguard Worker CHECK(data != nullptr);
482*795d594fSAndroid Build Coastguard Worker if (JvmtiErrorToException(env, jvmti_env, jvmti_env->SetThreadLocalStorage(thr, data))) {
483*795d594fSAndroid Build Coastguard Worker return;
484*795d594fSAndroid Build Coastguard Worker }
485*795d594fSAndroid Build Coastguard Worker if (JvmtiErrorToException(
486*795d594fSAndroid Build Coastguard Worker env,
487*795d594fSAndroid Build Coastguard Worker jvmti_env,
488*795d594fSAndroid Build Coastguard Worker jvmti_env->SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_FRAME_POP, thr))) {
489*795d594fSAndroid Build Coastguard Worker return;
490*795d594fSAndroid Build Coastguard Worker }
491*795d594fSAndroid Build Coastguard Worker if (JvmtiErrorToException(
492*795d594fSAndroid Build Coastguard Worker env,
493*795d594fSAndroid Build Coastguard Worker jvmti_env,
494*795d594fSAndroid Build Coastguard Worker jvmti_env->SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_BREAKPOINT, thr))) {
495*795d594fSAndroid Build Coastguard Worker return;
496*795d594fSAndroid Build Coastguard Worker }
497*795d594fSAndroid Build Coastguard Worker if (JvmtiErrorToException(
498*795d594fSAndroid Build Coastguard Worker env, jvmti_env, jvmti_env->SetBreakpoint(data->frame_pop_setup_method, 0))) {
499*795d594fSAndroid Build Coastguard Worker return;
500*795d594fSAndroid Build Coastguard Worker }
501*795d594fSAndroid Build Coastguard Worker }
502*795d594fSAndroid Build Coastguard Worker
Java_art_SuspendEvents_clearSuspendPopFrameEvent(JNIEnv * env,jclass klass,jthread thr)503*795d594fSAndroid Build Coastguard Worker extern "C" JNIEXPORT void JNICALL Java_art_SuspendEvents_clearSuspendPopFrameEvent(
504*795d594fSAndroid Build Coastguard Worker JNIEnv* env, [[maybe_unused]] jclass klass , jthread thr) {
505*795d594fSAndroid Build Coastguard Worker TestData* data;
506*795d594fSAndroid Build Coastguard Worker if (JvmtiErrorToException(
507*795d594fSAndroid Build Coastguard Worker env, jvmti_env, jvmti_env->GetThreadLocalStorage(thr, reinterpret_cast<void**>(&data)))) {
508*795d594fSAndroid Build Coastguard Worker return;
509*795d594fSAndroid Build Coastguard Worker }
510*795d594fSAndroid Build Coastguard Worker CHECK(data != nullptr);
511*795d594fSAndroid Build Coastguard Worker if (JvmtiErrorToException(
512*795d594fSAndroid Build Coastguard Worker env,
513*795d594fSAndroid Build Coastguard Worker jvmti_env,
514*795d594fSAndroid Build Coastguard Worker jvmti_env->SetEventNotificationMode(JVMTI_DISABLE, JVMTI_EVENT_FRAME_POP, thr))) {
515*795d594fSAndroid Build Coastguard Worker return;
516*795d594fSAndroid Build Coastguard Worker }
517*795d594fSAndroid Build Coastguard Worker if (JvmtiErrorToException(
518*795d594fSAndroid Build Coastguard Worker env,
519*795d594fSAndroid Build Coastguard Worker jvmti_env,
520*795d594fSAndroid Build Coastguard Worker jvmti_env->SetEventNotificationMode(JVMTI_DISABLE, JVMTI_EVENT_BREAKPOINT, thr))) {
521*795d594fSAndroid Build Coastguard Worker return;
522*795d594fSAndroid Build Coastguard Worker }
523*795d594fSAndroid Build Coastguard Worker if (JvmtiErrorToException(
524*795d594fSAndroid Build Coastguard Worker env, jvmti_env, jvmti_env->ClearBreakpoint(data->frame_pop_setup_method, 0))) {
525*795d594fSAndroid Build Coastguard Worker return;
526*795d594fSAndroid Build Coastguard Worker }
527*795d594fSAndroid Build Coastguard Worker DeleteTestData(env, thr, data);
528*795d594fSAndroid Build Coastguard Worker }
529*795d594fSAndroid Build Coastguard Worker
Java_art_SuspendEvents_setupSuspendBreakpointFor(JNIEnv * env,jclass klass,jobject meth,jlocation loc,jthread thr)530*795d594fSAndroid Build Coastguard Worker extern "C" JNIEXPORT void JNICALL Java_art_SuspendEvents_setupSuspendBreakpointFor(
531*795d594fSAndroid Build Coastguard Worker JNIEnv* env, [[maybe_unused]] jclass klass , jobject meth, jlocation loc, jthread thr) {
532*795d594fSAndroid Build Coastguard Worker TestData* data;
533*795d594fSAndroid Build Coastguard Worker if (JvmtiErrorToException(
534*795d594fSAndroid Build Coastguard Worker env, jvmti_env, jvmti_env->GetThreadLocalStorage(thr, reinterpret_cast<void**>(&data)))) {
535*795d594fSAndroid Build Coastguard Worker return;
536*795d594fSAndroid Build Coastguard Worker }
537*795d594fSAndroid Build Coastguard Worker CHECK(data == nullptr) << "Data was not cleared!";
538*795d594fSAndroid Build Coastguard Worker data = SetupTestData(env, meth, loc, nullptr, nullptr, nullptr, 0);
539*795d594fSAndroid Build Coastguard Worker if (data == nullptr) {
540*795d594fSAndroid Build Coastguard Worker return;
541*795d594fSAndroid Build Coastguard Worker }
542*795d594fSAndroid Build Coastguard Worker if (JvmtiErrorToException(env, jvmti_env, jvmti_env->SetThreadLocalStorage(thr, data))) {
543*795d594fSAndroid Build Coastguard Worker return;
544*795d594fSAndroid Build Coastguard Worker }
545*795d594fSAndroid Build Coastguard Worker if (JvmtiErrorToException(
546*795d594fSAndroid Build Coastguard Worker env,
547*795d594fSAndroid Build Coastguard Worker jvmti_env,
548*795d594fSAndroid Build Coastguard Worker jvmti_env->SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_BREAKPOINT, thr))) {
549*795d594fSAndroid Build Coastguard Worker return;
550*795d594fSAndroid Build Coastguard Worker }
551*795d594fSAndroid Build Coastguard Worker JvmtiErrorToException(
552*795d594fSAndroid Build Coastguard Worker env, jvmti_env, jvmti_env->SetBreakpoint(data->target_method, data->target_loc));
553*795d594fSAndroid Build Coastguard Worker }
554*795d594fSAndroid Build Coastguard Worker
Java_art_SuspendEvents_clearSuspendBreakpointFor(JNIEnv * env,jclass klass,jthread thr)555*795d594fSAndroid Build Coastguard Worker extern "C" JNIEXPORT void JNICALL Java_art_SuspendEvents_clearSuspendBreakpointFor(
556*795d594fSAndroid Build Coastguard Worker JNIEnv* env, [[maybe_unused]] jclass klass , jthread thr) {
557*795d594fSAndroid Build Coastguard Worker TestData* data;
558*795d594fSAndroid Build Coastguard Worker if (JvmtiErrorToException(
559*795d594fSAndroid Build Coastguard Worker env, jvmti_env, jvmti_env->GetThreadLocalStorage(thr, reinterpret_cast<void**>(&data)))) {
560*795d594fSAndroid Build Coastguard Worker return;
561*795d594fSAndroid Build Coastguard Worker }
562*795d594fSAndroid Build Coastguard Worker CHECK(data != nullptr);
563*795d594fSAndroid Build Coastguard Worker if (JvmtiErrorToException(
564*795d594fSAndroid Build Coastguard Worker env,
565*795d594fSAndroid Build Coastguard Worker jvmti_env,
566*795d594fSAndroid Build Coastguard Worker jvmti_env->SetEventNotificationMode(JVMTI_DISABLE, JVMTI_EVENT_BREAKPOINT, thr))) {
567*795d594fSAndroid Build Coastguard Worker return;
568*795d594fSAndroid Build Coastguard Worker }
569*795d594fSAndroid Build Coastguard Worker if (JvmtiErrorToException(
570*795d594fSAndroid Build Coastguard Worker env, jvmti_env, jvmti_env->ClearBreakpoint(data->target_method, data->target_loc))) {
571*795d594fSAndroid Build Coastguard Worker return;
572*795d594fSAndroid Build Coastguard Worker }
573*795d594fSAndroid Build Coastguard Worker if (JvmtiErrorToException(env, jvmti_env, jvmti_env->SetThreadLocalStorage(thr, nullptr))) {
574*795d594fSAndroid Build Coastguard Worker return;
575*795d594fSAndroid Build Coastguard Worker }
576*795d594fSAndroid Build Coastguard Worker DeleteTestData(env, thr, data);
577*795d594fSAndroid Build Coastguard Worker }
578*795d594fSAndroid Build Coastguard Worker
Java_art_SuspendEvents_setupSuspendExceptionEvent(JNIEnv * env,jclass klass,jobject method,jboolean is_catch,jthread thr)579*795d594fSAndroid Build Coastguard Worker extern "C" JNIEXPORT void JNICALL Java_art_SuspendEvents_setupSuspendExceptionEvent(
580*795d594fSAndroid Build Coastguard Worker JNIEnv* env, [[maybe_unused]] jclass klass , jobject method, jboolean is_catch, jthread thr) {
581*795d594fSAndroid Build Coastguard Worker TestData* data;
582*795d594fSAndroid Build Coastguard Worker if (JvmtiErrorToException(
583*795d594fSAndroid Build Coastguard Worker env, jvmti_env, jvmti_env->GetThreadLocalStorage(thr, reinterpret_cast<void**>(&data)))) {
584*795d594fSAndroid Build Coastguard Worker return;
585*795d594fSAndroid Build Coastguard Worker }
586*795d594fSAndroid Build Coastguard Worker CHECK(data == nullptr) << "Data was not cleared!";
587*795d594fSAndroid Build Coastguard Worker data = SetupTestData(env, method, 0, nullptr, nullptr, nullptr, 0);
588*795d594fSAndroid Build Coastguard Worker if (data == nullptr) {
589*795d594fSAndroid Build Coastguard Worker return;
590*795d594fSAndroid Build Coastguard Worker }
591*795d594fSAndroid Build Coastguard Worker if (JvmtiErrorToException(env, jvmti_env, jvmti_env->SetThreadLocalStorage(thr, data))) {
592*795d594fSAndroid Build Coastguard Worker return;
593*795d594fSAndroid Build Coastguard Worker }
594*795d594fSAndroid Build Coastguard Worker JvmtiErrorToException(
595*795d594fSAndroid Build Coastguard Worker env,
596*795d594fSAndroid Build Coastguard Worker jvmti_env,
597*795d594fSAndroid Build Coastguard Worker jvmti_env->SetEventNotificationMode(
598*795d594fSAndroid Build Coastguard Worker JVMTI_ENABLE, is_catch ? JVMTI_EVENT_EXCEPTION_CATCH : JVMTI_EVENT_EXCEPTION, thr));
599*795d594fSAndroid Build Coastguard Worker }
600*795d594fSAndroid Build Coastguard Worker
Java_art_SuspendEvents_clearSuspendExceptionEvent(JNIEnv * env,jclass klass,jthread thr)601*795d594fSAndroid Build Coastguard Worker extern "C" JNIEXPORT void JNICALL Java_art_SuspendEvents_clearSuspendExceptionEvent(
602*795d594fSAndroid Build Coastguard Worker JNIEnv* env, [[maybe_unused]] jclass klass , jthread thr) {
603*795d594fSAndroid Build Coastguard Worker TestData* data;
604*795d594fSAndroid Build Coastguard Worker if (JvmtiErrorToException(
605*795d594fSAndroid Build Coastguard Worker env, jvmti_env, jvmti_env->GetThreadLocalStorage(thr, reinterpret_cast<void**>(&data)))) {
606*795d594fSAndroid Build Coastguard Worker return;
607*795d594fSAndroid Build Coastguard Worker }
608*795d594fSAndroid Build Coastguard Worker CHECK(data != nullptr);
609*795d594fSAndroid Build Coastguard Worker if (JvmtiErrorToException(
610*795d594fSAndroid Build Coastguard Worker env,
611*795d594fSAndroid Build Coastguard Worker jvmti_env,
612*795d594fSAndroid Build Coastguard Worker jvmti_env->SetEventNotificationMode(JVMTI_DISABLE, JVMTI_EVENT_EXCEPTION_CATCH, thr))) {
613*795d594fSAndroid Build Coastguard Worker return;
614*795d594fSAndroid Build Coastguard Worker }
615*795d594fSAndroid Build Coastguard Worker if (JvmtiErrorToException(
616*795d594fSAndroid Build Coastguard Worker env,
617*795d594fSAndroid Build Coastguard Worker jvmti_env,
618*795d594fSAndroid Build Coastguard Worker jvmti_env->SetEventNotificationMode(JVMTI_DISABLE, JVMTI_EVENT_EXCEPTION, thr))) {
619*795d594fSAndroid Build Coastguard Worker return;
620*795d594fSAndroid Build Coastguard Worker }
621*795d594fSAndroid Build Coastguard Worker DeleteTestData(env, thr, data);
622*795d594fSAndroid Build Coastguard Worker }
623*795d594fSAndroid Build Coastguard Worker
Java_art_SuspendEvents_setupSuspendMethodEvent(JNIEnv * env,jclass klass,jobject method,jboolean enter,jthread thr)624*795d594fSAndroid Build Coastguard Worker extern "C" JNIEXPORT void JNICALL Java_art_SuspendEvents_setupSuspendMethodEvent(
625*795d594fSAndroid Build Coastguard Worker JNIEnv* env, [[maybe_unused]] jclass klass , jobject method, jboolean enter, jthread thr) {
626*795d594fSAndroid Build Coastguard Worker TestData* data;
627*795d594fSAndroid Build Coastguard Worker if (JvmtiErrorToException(
628*795d594fSAndroid Build Coastguard Worker env, jvmti_env, jvmti_env->GetThreadLocalStorage(thr, reinterpret_cast<void**>(&data)))) {
629*795d594fSAndroid Build Coastguard Worker return;
630*795d594fSAndroid Build Coastguard Worker }
631*795d594fSAndroid Build Coastguard Worker CHECK(data == nullptr) << "Data was not cleared!";
632*795d594fSAndroid Build Coastguard Worker data = SetupTestData(env, method, 0, nullptr, nullptr, nullptr, 0);
633*795d594fSAndroid Build Coastguard Worker if (data == nullptr) {
634*795d594fSAndroid Build Coastguard Worker return;
635*795d594fSAndroid Build Coastguard Worker }
636*795d594fSAndroid Build Coastguard Worker if (JvmtiErrorToException(env, jvmti_env, jvmti_env->SetThreadLocalStorage(thr, data))) {
637*795d594fSAndroid Build Coastguard Worker return;
638*795d594fSAndroid Build Coastguard Worker }
639*795d594fSAndroid Build Coastguard Worker JvmtiErrorToException(
640*795d594fSAndroid Build Coastguard Worker env,
641*795d594fSAndroid Build Coastguard Worker jvmti_env,
642*795d594fSAndroid Build Coastguard Worker jvmti_env->SetEventNotificationMode(
643*795d594fSAndroid Build Coastguard Worker JVMTI_ENABLE, enter ? JVMTI_EVENT_METHOD_ENTRY : JVMTI_EVENT_METHOD_EXIT, thr));
644*795d594fSAndroid Build Coastguard Worker }
645*795d594fSAndroid Build Coastguard Worker
Java_art_SuspendEvents_clearSuspendMethodEvent(JNIEnv * env,jclass klass,jthread thr)646*795d594fSAndroid Build Coastguard Worker extern "C" JNIEXPORT void JNICALL Java_art_SuspendEvents_clearSuspendMethodEvent(
647*795d594fSAndroid Build Coastguard Worker JNIEnv* env, [[maybe_unused]] jclass klass , jthread thr) {
648*795d594fSAndroid Build Coastguard Worker TestData* data;
649*795d594fSAndroid Build Coastguard Worker if (JvmtiErrorToException(
650*795d594fSAndroid Build Coastguard Worker env, jvmti_env, jvmti_env->GetThreadLocalStorage(thr, reinterpret_cast<void**>(&data)))) {
651*795d594fSAndroid Build Coastguard Worker return;
652*795d594fSAndroid Build Coastguard Worker }
653*795d594fSAndroid Build Coastguard Worker CHECK(data != nullptr);
654*795d594fSAndroid Build Coastguard Worker if (JvmtiErrorToException(
655*795d594fSAndroid Build Coastguard Worker env,
656*795d594fSAndroid Build Coastguard Worker jvmti_env,
657*795d594fSAndroid Build Coastguard Worker jvmti_env->SetEventNotificationMode(JVMTI_DISABLE, JVMTI_EVENT_METHOD_EXIT, thr))) {
658*795d594fSAndroid Build Coastguard Worker return;
659*795d594fSAndroid Build Coastguard Worker }
660*795d594fSAndroid Build Coastguard Worker if (JvmtiErrorToException(
661*795d594fSAndroid Build Coastguard Worker env,
662*795d594fSAndroid Build Coastguard Worker jvmti_env,
663*795d594fSAndroid Build Coastguard Worker jvmti_env->SetEventNotificationMode(JVMTI_DISABLE, JVMTI_EVENT_METHOD_ENTRY, thr))) {
664*795d594fSAndroid Build Coastguard Worker return;
665*795d594fSAndroid Build Coastguard Worker }
666*795d594fSAndroid Build Coastguard Worker DeleteTestData(env, thr, data);
667*795d594fSAndroid Build Coastguard Worker }
668*795d594fSAndroid Build Coastguard Worker
669*795d594fSAndroid Build Coastguard Worker extern "C" JNIEXPORT void JNICALL
Java_art_SuspendEvents_setupFieldSuspendFor(JNIEnv * env,jclass klass,jclass target_klass,jobject field,jboolean access,jthread thr)670*795d594fSAndroid Build Coastguard Worker Java_art_SuspendEvents_setupFieldSuspendFor(JNIEnv* env,
671*795d594fSAndroid Build Coastguard Worker [[maybe_unused]] jclass klass,
672*795d594fSAndroid Build Coastguard Worker jclass target_klass,
673*795d594fSAndroid Build Coastguard Worker jobject field,
674*795d594fSAndroid Build Coastguard Worker jboolean access,
675*795d594fSAndroid Build Coastguard Worker jthread thr) {
676*795d594fSAndroid Build Coastguard Worker TestData* data;
677*795d594fSAndroid Build Coastguard Worker if (JvmtiErrorToException(
678*795d594fSAndroid Build Coastguard Worker env, jvmti_env, jvmti_env->GetThreadLocalStorage(thr, reinterpret_cast<void**>(&data)))) {
679*795d594fSAndroid Build Coastguard Worker return;
680*795d594fSAndroid Build Coastguard Worker }
681*795d594fSAndroid Build Coastguard Worker CHECK(data == nullptr) << "Data was not cleared!";
682*795d594fSAndroid Build Coastguard Worker data = SetupTestData(env, nullptr, 0, target_klass, field, nullptr, 0);
683*795d594fSAndroid Build Coastguard Worker if (data == nullptr) {
684*795d594fSAndroid Build Coastguard Worker return;
685*795d594fSAndroid Build Coastguard Worker }
686*795d594fSAndroid Build Coastguard Worker if (JvmtiErrorToException(env, jvmti_env, jvmti_env->SetThreadLocalStorage(thr, data))) {
687*795d594fSAndroid Build Coastguard Worker return;
688*795d594fSAndroid Build Coastguard Worker }
689*795d594fSAndroid Build Coastguard Worker if (JvmtiErrorToException(env,
690*795d594fSAndroid Build Coastguard Worker jvmti_env,
691*795d594fSAndroid Build Coastguard Worker jvmti_env->SetEventNotificationMode(
692*795d594fSAndroid Build Coastguard Worker JVMTI_ENABLE,
693*795d594fSAndroid Build Coastguard Worker access ? JVMTI_EVENT_FIELD_ACCESS : JVMTI_EVENT_FIELD_MODIFICATION,
694*795d594fSAndroid Build Coastguard Worker thr))) {
695*795d594fSAndroid Build Coastguard Worker return;
696*795d594fSAndroid Build Coastguard Worker }
697*795d594fSAndroid Build Coastguard Worker if (access) {
698*795d594fSAndroid Build Coastguard Worker JvmtiErrorToException(
699*795d594fSAndroid Build Coastguard Worker env, jvmti_env, jvmti_env->SetFieldAccessWatch(data->target_klass, data->target_field));
700*795d594fSAndroid Build Coastguard Worker } else {
701*795d594fSAndroid Build Coastguard Worker JvmtiErrorToException(
702*795d594fSAndroid Build Coastguard Worker env,
703*795d594fSAndroid Build Coastguard Worker jvmti_env,
704*795d594fSAndroid Build Coastguard Worker jvmti_env->SetFieldModificationWatch(data->target_klass, data->target_field));
705*795d594fSAndroid Build Coastguard Worker }
706*795d594fSAndroid Build Coastguard Worker }
707*795d594fSAndroid Build Coastguard Worker
Java_art_SuspendEvents_clearFieldSuspendFor(JNIEnv * env,jclass klass,jthread thr)708*795d594fSAndroid Build Coastguard Worker extern "C" JNIEXPORT void JNICALL Java_art_SuspendEvents_clearFieldSuspendFor(
709*795d594fSAndroid Build Coastguard Worker JNIEnv* env, [[maybe_unused]] jclass klass , jthread thr) {
710*795d594fSAndroid Build Coastguard Worker TestData* data;
711*795d594fSAndroid Build Coastguard Worker if (JvmtiErrorToException(
712*795d594fSAndroid Build Coastguard Worker env, jvmti_env, jvmti_env->GetThreadLocalStorage(thr, reinterpret_cast<void**>(&data)))) {
713*795d594fSAndroid Build Coastguard Worker return;
714*795d594fSAndroid Build Coastguard Worker }
715*795d594fSAndroid Build Coastguard Worker CHECK(data != nullptr);
716*795d594fSAndroid Build Coastguard Worker if (JvmtiErrorToException(
717*795d594fSAndroid Build Coastguard Worker env,
718*795d594fSAndroid Build Coastguard Worker jvmti_env,
719*795d594fSAndroid Build Coastguard Worker jvmti_env->SetEventNotificationMode(JVMTI_DISABLE, JVMTI_EVENT_FIELD_ACCESS, thr))) {
720*795d594fSAndroid Build Coastguard Worker return;
721*795d594fSAndroid Build Coastguard Worker }
722*795d594fSAndroid Build Coastguard Worker if (JvmtiErrorToException(env,
723*795d594fSAndroid Build Coastguard Worker jvmti_env,
724*795d594fSAndroid Build Coastguard Worker jvmti_env->SetEventNotificationMode(
725*795d594fSAndroid Build Coastguard Worker JVMTI_DISABLE, JVMTI_EVENT_FIELD_MODIFICATION, thr))) {
726*795d594fSAndroid Build Coastguard Worker return;
727*795d594fSAndroid Build Coastguard Worker }
728*795d594fSAndroid Build Coastguard Worker if (JvmtiErrorToException(
729*795d594fSAndroid Build Coastguard Worker env,
730*795d594fSAndroid Build Coastguard Worker jvmti_env,
731*795d594fSAndroid Build Coastguard Worker jvmti_env->ClearFieldModificationWatch(data->target_klass, data->target_field)) &&
732*795d594fSAndroid Build Coastguard Worker JvmtiErrorToException(
733*795d594fSAndroid Build Coastguard Worker env,
734*795d594fSAndroid Build Coastguard Worker jvmti_env,
735*795d594fSAndroid Build Coastguard Worker jvmti_env->ClearFieldAccessWatch(data->target_klass, data->target_field))) {
736*795d594fSAndroid Build Coastguard Worker return;
737*795d594fSAndroid Build Coastguard Worker } else {
738*795d594fSAndroid Build Coastguard Worker env->ExceptionClear();
739*795d594fSAndroid Build Coastguard Worker }
740*795d594fSAndroid Build Coastguard Worker if (JvmtiErrorToException(env, jvmti_env, jvmti_env->SetThreadLocalStorage(thr, nullptr))) {
741*795d594fSAndroid Build Coastguard Worker return;
742*795d594fSAndroid Build Coastguard Worker }
743*795d594fSAndroid Build Coastguard Worker DeleteTestData(env, thr, data);
744*795d594fSAndroid Build Coastguard Worker }
745*795d594fSAndroid Build Coastguard Worker
Java_art_SuspendEvents_setupWaitForNativeCall(JNIEnv * env,jclass klass,jthread thr)746*795d594fSAndroid Build Coastguard Worker extern "C" JNIEXPORT void JNICALL Java_art_SuspendEvents_setupWaitForNativeCall(
747*795d594fSAndroid Build Coastguard Worker JNIEnv* env, [[maybe_unused]] jclass klass , jthread thr) {
748*795d594fSAndroid Build Coastguard Worker TestData* data;
749*795d594fSAndroid Build Coastguard Worker if (JvmtiErrorToException(
750*795d594fSAndroid Build Coastguard Worker env, jvmti_env, jvmti_env->GetThreadLocalStorage(thr, reinterpret_cast<void**>(&data)))) {
751*795d594fSAndroid Build Coastguard Worker return;
752*795d594fSAndroid Build Coastguard Worker }
753*795d594fSAndroid Build Coastguard Worker CHECK(data == nullptr) << "Data was not cleared!";
754*795d594fSAndroid Build Coastguard Worker data = SetupTestData(env, nullptr, 0, nullptr, nullptr, nullptr, 0);
755*795d594fSAndroid Build Coastguard Worker if (data == nullptr) {
756*795d594fSAndroid Build Coastguard Worker return;
757*795d594fSAndroid Build Coastguard Worker }
758*795d594fSAndroid Build Coastguard Worker if (JvmtiErrorToException(env, jvmti_env, jvmti_env->SetThreadLocalStorage(thr, data))) {
759*795d594fSAndroid Build Coastguard Worker return;
760*795d594fSAndroid Build Coastguard Worker }
761*795d594fSAndroid Build Coastguard Worker }
762*795d594fSAndroid Build Coastguard Worker
Java_art_SuspendEvents_clearWaitForNativeCall(JNIEnv * env,jclass klass,jthread thr)763*795d594fSAndroid Build Coastguard Worker extern "C" JNIEXPORT void JNICALL Java_art_SuspendEvents_clearWaitForNativeCall(
764*795d594fSAndroid Build Coastguard Worker JNIEnv* env, [[maybe_unused]] jclass klass , jthread thr) {
765*795d594fSAndroid Build Coastguard Worker TestData* data;
766*795d594fSAndroid Build Coastguard Worker if (JvmtiErrorToException(
767*795d594fSAndroid Build Coastguard Worker env, jvmti_env, jvmti_env->GetThreadLocalStorage(thr, reinterpret_cast<void**>(&data)))) {
768*795d594fSAndroid Build Coastguard Worker return;
769*795d594fSAndroid Build Coastguard Worker }
770*795d594fSAndroid Build Coastguard Worker CHECK(data != nullptr);
771*795d594fSAndroid Build Coastguard Worker if (JvmtiErrorToException(env, jvmti_env, jvmti_env->SetThreadLocalStorage(thr, nullptr))) {
772*795d594fSAndroid Build Coastguard Worker return;
773*795d594fSAndroid Build Coastguard Worker }
774*795d594fSAndroid Build Coastguard Worker DeleteTestData(env, thr, data);
775*795d594fSAndroid Build Coastguard Worker }
776*795d594fSAndroid Build Coastguard Worker
777*795d594fSAndroid Build Coastguard Worker extern "C" JNIEXPORT void JNICALL
Java_art_SuspendEvents_waitForSuspendHit(JNIEnv * env,jclass klass,jthread thr)778*795d594fSAndroid Build Coastguard Worker Java_art_SuspendEvents_waitForSuspendHit(JNIEnv* env, [[maybe_unused]] jclass klass, jthread thr) {
779*795d594fSAndroid Build Coastguard Worker TestData* data;
780*795d594fSAndroid Build Coastguard Worker if (JvmtiErrorToException(
781*795d594fSAndroid Build Coastguard Worker env, jvmti_env, jvmti_env->GetThreadLocalStorage(thr, reinterpret_cast<void**>(&data)))) {
782*795d594fSAndroid Build Coastguard Worker return;
783*795d594fSAndroid Build Coastguard Worker }
784*795d594fSAndroid Build Coastguard Worker CHECK(data != nullptr);
785*795d594fSAndroid Build Coastguard Worker if (JvmtiErrorToException(env, jvmti_env, jvmti_env->RawMonitorEnter(data->notify_monitor))) {
786*795d594fSAndroid Build Coastguard Worker return;
787*795d594fSAndroid Build Coastguard Worker }
788*795d594fSAndroid Build Coastguard Worker while (!data->hit_location) {
789*795d594fSAndroid Build Coastguard Worker if (JvmtiErrorToException(
790*795d594fSAndroid Build Coastguard Worker env, jvmti_env, jvmti_env->RawMonitorWait(data->notify_monitor, -1))) {
791*795d594fSAndroid Build Coastguard Worker return;
792*795d594fSAndroid Build Coastguard Worker }
793*795d594fSAndroid Build Coastguard Worker }
794*795d594fSAndroid Build Coastguard Worker if (JvmtiErrorToException(env, jvmti_env, jvmti_env->RawMonitorExit(data->notify_monitor))) {
795*795d594fSAndroid Build Coastguard Worker return;
796*795d594fSAndroid Build Coastguard Worker }
797*795d594fSAndroid Build Coastguard Worker jint state = 0;
798*795d594fSAndroid Build Coastguard Worker while (!JvmtiErrorToException(env, jvmti_env, jvmti_env->GetThreadState(thr, &state)) &&
799*795d594fSAndroid Build Coastguard Worker (state & JVMTI_THREAD_STATE_SUSPENDED) == 0) {
800*795d594fSAndroid Build Coastguard Worker }
801*795d594fSAndroid Build Coastguard Worker }
802*795d594fSAndroid Build Coastguard Worker } // namespace common_suspend_event
803*795d594fSAndroid Build Coastguard Worker } // namespace art
804