39
40 /* test objects */
41 static jthread threadForStop = NULL;
42 static jthread threadForInterrupt = NULL;
43 static int ThreadDeathFlag = 0;
44 static int InterruptedExceptionFlag = 0;
45
46 /* ========================================================================== */
47
48 /** callback functions **/
49
50 const char* THREAD_DEATH_CLASS_SIG = "Ljava/lang/ThreadDeath;";
51 const char* INTERRUPTED_EXCEPTION_CLASS_SIG = "Ljava/lang/InterruptedException;";
52 static void JNICALL
53 Exception(jvmtiEnv *jvmti_env, JNIEnv *jni_env, jthread thread,
54 jmethodID method, jlocation location, jobject exception,
55 jmethodID catch_method, jlocation catch_location) {
56 jclass klass = NULL;
57 char *signature = NULL;
58
59 if (!NSK_JNI_VERIFY(jni_env, (klass =
60 NSK_CPP_STUB2(GetObjectClass, jni_env, exception)) != NULL)) {
61 nsk_jvmti_setFailStatus();
62 return;
63 }
64
65 if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB4(GetClassSignature, jvmti_env,
66 klass, &signature, NULL))) {
67 nsk_jvmti_setFailStatus();
68 return;
69 }
70
71 if (!NSK_VERIFY(signature != NULL)) {
72 nsk_jvmti_setFailStatus();
73 return;
74 }
75
76 NSK_DISPLAY1("Exception event: %s\n", signature);
77
78 if (NSK_CPP_STUB3(IsSameObject, jni_env, threadForInterrupt, thread)) {
79 if (strcmp(signature, INTERRUPTED_EXCEPTION_CLASS_SIG) == 0) {
80 InterruptedExceptionFlag++;
81 } else {
82 NSK_COMPLAIN1("Unexpected exception in DebuggeeThreadForInterrupt: %s\n",
83 signature);
84 nsk_jvmti_setFailStatus();
85 }
86 } else if (NSK_CPP_STUB3(IsSameObject, jni_env, threadForStop, thread)) {
87 if (strcmp(signature, THREAD_DEATH_CLASS_SIG) == 0) {
88 ThreadDeathFlag++;
89 } else {
90 NSK_COMPLAIN1("Unexpected exception in DebuggeeThreadForStop: %s\n",
91 signature);
92 nsk_jvmti_setFailStatus();
93 }
94 }
95
96 NSK_CPP_STUB2(Deallocate, jvmti_env, (unsigned char*)signature);
97 }
98
99 /* ========================================================================== */
100
101 static int prepare(jvmtiEnv* jvmti, JNIEnv* jni) {
102 const char* STOP_THREAD_NAME = "DebuggeeThreadForStop";
103 const char* INTERRUPT_THREAD_NAME = "DebuggeeThreadForInterrupt";
104 jvmtiThreadInfo info;
105 jthread *threads = NULL;
106 jint threads_count = 0;
107 int i;
108
109 NSK_DISPLAY0("Prepare: find tested thread\n");
110
111 /* get all live threads */
112 if (!NSK_JVMTI_VERIFY(
113 NSK_CPP_STUB3(GetAllThreads, jvmti, &threads_count, &threads)))
114 return NSK_FALSE;
115
116 if (!NSK_VERIFY(threads_count > 0 && threads != NULL))
117 return NSK_FALSE;
118
119 /* find tested thread */
120 for (i = 0; i < threads_count; i++) {
121 if (!NSK_VERIFY(threads[i] != NULL))
122 return NSK_FALSE;
123
124 /* get thread information */
125 if (!NSK_JVMTI_VERIFY(
126 NSK_CPP_STUB3(GetThreadInfo, jvmti, threads[i], &info)))
127 return NSK_FALSE;
128
129 NSK_DISPLAY3(" thread #%d (%s): %p\n", i, info.name, threads[i]);
130
131 /* find by name */
132 if (info.name != NULL) {
133 if (strcmp(info.name, STOP_THREAD_NAME) == 0) {
134 threadForStop = threads[i];
135 } else if (strcmp(info.name, INTERRUPT_THREAD_NAME) == 0) {
136 threadForInterrupt = threads[i];
137 }
138 }
139 }
140
141 /* deallocate threads list */
142 if (!NSK_JVMTI_VERIFY(
143 NSK_CPP_STUB2(Deallocate, jvmti, (unsigned char*)threads)))
144 return NSK_FALSE;
145
146 if (threadForStop == NULL) {
147 NSK_COMPLAIN0("DebuggeeThreadForStop not found");
148 return NSK_FALSE;
149 }
150
151 if (threadForInterrupt == NULL) {
152 NSK_COMPLAIN0("DebuggeeThreadForInterrupt not found");
153 return NSK_FALSE;
154 }
155
156 if (!NSK_JNI_VERIFY(jni, (threadForStop =
157 NSK_CPP_STUB2(NewGlobalRef, jni, threadForStop)) != NULL))
158 return NSK_FALSE;
159
160 if (!NSK_JNI_VERIFY(jni, (threadForInterrupt =
161 NSK_CPP_STUB2(NewGlobalRef, jni, threadForInterrupt)) != NULL))
162 return NSK_FALSE;
163
164 /* enable event */
165 if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB4(SetEventNotificationMode,
166 jvmti, JVMTI_ENABLE, JVMTI_EVENT_EXCEPTION, NULL)))
167 return NSK_FALSE;
168
169 return NSK_TRUE;
170 }
171
172 /* ========================================================================== */
173
174 /** Agent algorithm. */
175 static void JNICALL
176 agentProc(jvmtiEnv* jvmti, JNIEnv* jni, void* arg) {
177
178 if (!nsk_jvmti_waitForSync(timeout))
179 return;
180
181 if (!prepare(jvmti, jni)) {
182 nsk_jvmti_setFailStatus();
183 return;
184 }
185
186 /* resume debugee and wait for sync */
187 if (!nsk_jvmti_resumeSync())
188 return;
189 if (!nsk_jvmti_waitForSync(timeout))
190 return;
191
192 NSK_DISPLAY1("ThreadDeath received: %d\n", ThreadDeathFlag);
193 if (!NSK_VERIFY(ThreadDeathFlag))
194 nsk_jvmti_setFailStatus();
195
196 NSK_DISPLAY1("InterruptedException received: %d\n",
197 InterruptedExceptionFlag);
198 if (!NSK_VERIFY(InterruptedExceptionFlag))
199 nsk_jvmti_setFailStatus();
200
201 /* disable event */
202 if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB4(SetEventNotificationMode,
203 jvmti, JVMTI_DISABLE, JVMTI_EVENT_EXCEPTION, NULL)))
204 nsk_jvmti_setFailStatus();
205
206 NSK_TRACE(NSK_CPP_STUB2(DeleteGlobalRef, jni, threadForStop));
207 NSK_TRACE(NSK_CPP_STUB2(DeleteGlobalRef, jni, threadForInterrupt));
208
209 if (!nsk_jvmti_resumeSync())
210 return;
211 }
212
213 /* ========================================================================== */
214
215 /** Agent library initialization. */
216 #ifdef STATIC_BUILD
217 JNIEXPORT jint JNICALL Agent_OnLoad_ma08t001a(JavaVM *jvm, char *options, void *reserved) {
218 return Agent_Initialize(jvm, options, reserved);
219 }
220 JNIEXPORT jint JNICALL Agent_OnAttach_ma08t001a(JavaVM *jvm, char *options, void *reserved) {
221 return Agent_Initialize(jvm, options, reserved);
222 }
223 JNIEXPORT jint JNI_OnLoad_ma08t001a(JavaVM *jvm, char *options, void *reserved) {
224 return JNI_VERSION_1_8;
225 }
226 #endif
227 jint Agent_Initialize(JavaVM *jvm, char *options, void *reserved) {
228 jvmtiEnv* jvmti = NULL;
229 jvmtiCapabilities caps;
230 jvmtiEventCallbacks callbacks;
231
232 NSK_DISPLAY0("Agent_OnLoad\n");
233
234 if (!NSK_VERIFY(nsk_jvmti_parseOptions(options)))
235 return JNI_ERR;
236
237 timeout = nsk_jvmti_getWaitTime() * 60 * 1000;
238
239 if (!NSK_VERIFY((jvmti =
240 nsk_jvmti_createJVMTIEnv(jvm, reserved)) != NULL))
241 return JNI_ERR;
242
243 if (!NSK_VERIFY(nsk_jvmti_setAgentProc(agentProc, NULL)))
244 return JNI_ERR;
245
246 memset(&caps, 0, sizeof(caps));
247 caps.can_generate_exception_events = 1;
248 if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB2(AddCapabilities, jvmti, &caps))) {
249 return JNI_ERR;
250 }
251
252 memset(&callbacks, 0, sizeof(callbacks));
253 callbacks.Exception = &Exception;
254 if (!NSK_VERIFY(nsk_jvmti_init_MA(&callbacks)))
255 return JNI_ERR;
256
257 return JNI_OK;
258 }
259
260 /* ========================================================================== */
261
262 }
|
39
40 /* test objects */
41 static jthread threadForStop = NULL;
42 static jthread threadForInterrupt = NULL;
43 static int ThreadDeathFlag = 0;
44 static int InterruptedExceptionFlag = 0;
45
46 /* ========================================================================== */
47
48 /** callback functions **/
49
50 const char* THREAD_DEATH_CLASS_SIG = "Ljava/lang/ThreadDeath;";
51 const char* INTERRUPTED_EXCEPTION_CLASS_SIG = "Ljava/lang/InterruptedException;";
52 static void JNICALL
53 Exception(jvmtiEnv *jvmti_env, JNIEnv *jni_env, jthread thread,
54 jmethodID method, jlocation location, jobject exception,
55 jmethodID catch_method, jlocation catch_location) {
56 jclass klass = NULL;
57 char *signature = NULL;
58
59 if (!NSK_JNI_VERIFY(jni_env, (klass = jni_env->GetObjectClass(exception)) != NULL)) {
60 nsk_jvmti_setFailStatus();
61 return;
62 }
63
64 if (!NSK_JVMTI_VERIFY(jvmti_env->GetClassSignature(klass, &signature, NULL))) {
65 nsk_jvmti_setFailStatus();
66 return;
67 }
68
69 if (!NSK_VERIFY(signature != NULL)) {
70 nsk_jvmti_setFailStatus();
71 return;
72 }
73
74 NSK_DISPLAY1("Exception event: %s\n", signature);
75
76 if (jni_env->IsSameObject(threadForInterrupt, thread)) {
77 if (strcmp(signature, INTERRUPTED_EXCEPTION_CLASS_SIG) == 0) {
78 InterruptedExceptionFlag++;
79 } else {
80 NSK_COMPLAIN1("Unexpected exception in DebuggeeThreadForInterrupt: %s\n",
81 signature);
82 nsk_jvmti_setFailStatus();
83 }
84 } else if (jni_env->IsSameObject(threadForStop, thread)) {
85 if (strcmp(signature, THREAD_DEATH_CLASS_SIG) == 0) {
86 ThreadDeathFlag++;
87 } else {
88 NSK_COMPLAIN1("Unexpected exception in DebuggeeThreadForStop: %s\n",
89 signature);
90 nsk_jvmti_setFailStatus();
91 }
92 }
93
94 jvmti_env->Deallocate((unsigned char*)signature);
95 }
96
97 /* ========================================================================== */
98
99 static int prepare(jvmtiEnv* jvmti, JNIEnv* jni) {
100 const char* STOP_THREAD_NAME = "DebuggeeThreadForStop";
101 const char* INTERRUPT_THREAD_NAME = "DebuggeeThreadForInterrupt";
102 jvmtiThreadInfo info;
103 jthread *threads = NULL;
104 jint threads_count = 0;
105 int i;
106
107 NSK_DISPLAY0("Prepare: find tested thread\n");
108
109 /* get all live threads */
110 if (!NSK_JVMTI_VERIFY(jvmti->GetAllThreads(&threads_count, &threads)))
111 return NSK_FALSE;
112
113 if (!NSK_VERIFY(threads_count > 0 && threads != NULL))
114 return NSK_FALSE;
115
116 /* find tested thread */
117 for (i = 0; i < threads_count; i++) {
118 if (!NSK_VERIFY(threads[i] != NULL))
119 return NSK_FALSE;
120
121 /* get thread information */
122 if (!NSK_JVMTI_VERIFY(jvmti->GetThreadInfo(threads[i], &info)))
123 return NSK_FALSE;
124
125 NSK_DISPLAY3(" thread #%d (%s): %p\n", i, info.name, threads[i]);
126
127 /* find by name */
128 if (info.name != NULL) {
129 if (strcmp(info.name, STOP_THREAD_NAME) == 0) {
130 threadForStop = threads[i];
131 } else if (strcmp(info.name, INTERRUPT_THREAD_NAME) == 0) {
132 threadForInterrupt = threads[i];
133 }
134 }
135 }
136
137 /* deallocate threads list */
138 if (!NSK_JVMTI_VERIFY(jvmti->Deallocate((unsigned char*)threads)))
139 return NSK_FALSE;
140
141 if (threadForStop == NULL) {
142 NSK_COMPLAIN0("DebuggeeThreadForStop not found");
143 return NSK_FALSE;
144 }
145
146 if (threadForInterrupt == NULL) {
147 NSK_COMPLAIN0("DebuggeeThreadForInterrupt not found");
148 return NSK_FALSE;
149 }
150
151 if (!NSK_JNI_VERIFY(jni, (threadForStop = jni->NewGlobalRef(threadForStop)) != NULL))
152 return NSK_FALSE;
153
154 if (!NSK_JNI_VERIFY(jni, (threadForInterrupt = jni->NewGlobalRef(threadForInterrupt)) != NULL))
155 return NSK_FALSE;
156
157 /* enable event */
158 if (!NSK_JVMTI_VERIFY(jvmti->SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_EXCEPTION, NULL)))
159 return NSK_FALSE;
160
161 return NSK_TRUE;
162 }
163
164 /* ========================================================================== */
165
166 /** Agent algorithm. */
167 static void JNICALL
168 agentProc(jvmtiEnv* jvmti, JNIEnv* jni, void* arg) {
169
170 if (!nsk_jvmti_waitForSync(timeout))
171 return;
172
173 if (!prepare(jvmti, jni)) {
174 nsk_jvmti_setFailStatus();
175 return;
176 }
177
178 /* resume debugee and wait for sync */
179 if (!nsk_jvmti_resumeSync())
180 return;
181 if (!nsk_jvmti_waitForSync(timeout))
182 return;
183
184 NSK_DISPLAY1("ThreadDeath received: %d\n", ThreadDeathFlag);
185 if (!NSK_VERIFY(ThreadDeathFlag))
186 nsk_jvmti_setFailStatus();
187
188 NSK_DISPLAY1("InterruptedException received: %d\n",
189 InterruptedExceptionFlag);
190 if (!NSK_VERIFY(InterruptedExceptionFlag))
191 nsk_jvmti_setFailStatus();
192
193 /* disable event */
194 if (!NSK_JVMTI_VERIFY(jvmti->SetEventNotificationMode(JVMTI_DISABLE, JVMTI_EVENT_EXCEPTION, NULL)))
195 nsk_jvmti_setFailStatus();
196
197 NSK_TRACE(jni->DeleteGlobalRef(threadForStop));
198 NSK_TRACE(jni->DeleteGlobalRef(threadForInterrupt));
199
200 if (!nsk_jvmti_resumeSync())
201 return;
202 }
203
204 /* ========================================================================== */
205
206 /** Agent library initialization. */
207 #ifdef STATIC_BUILD
208 JNIEXPORT jint JNICALL Agent_OnLoad_ma08t001a(JavaVM *jvm, char *options, void *reserved) {
209 return Agent_Initialize(jvm, options, reserved);
210 }
211 JNIEXPORT jint JNICALL Agent_OnAttach_ma08t001a(JavaVM *jvm, char *options, void *reserved) {
212 return Agent_Initialize(jvm, options, reserved);
213 }
214 JNIEXPORT jint JNI_OnLoad_ma08t001a(JavaVM *jvm, char *options, void *reserved) {
215 return JNI_VERSION_1_8;
216 }
217 #endif
218 jint Agent_Initialize(JavaVM *jvm, char *options, void *reserved) {
219 jvmtiEnv* jvmti = NULL;
220 jvmtiCapabilities caps;
221 jvmtiEventCallbacks callbacks;
222
223 NSK_DISPLAY0("Agent_OnLoad\n");
224
225 if (!NSK_VERIFY(nsk_jvmti_parseOptions(options)))
226 return JNI_ERR;
227
228 timeout = nsk_jvmti_getWaitTime() * 60 * 1000;
229
230 if (!NSK_VERIFY((jvmti =
231 nsk_jvmti_createJVMTIEnv(jvm, reserved)) != NULL))
232 return JNI_ERR;
233
234 if (!NSK_VERIFY(nsk_jvmti_setAgentProc(agentProc, NULL)))
235 return JNI_ERR;
236
237 memset(&caps, 0, sizeof(caps));
238 caps.can_generate_exception_events = 1;
239 if (!NSK_JVMTI_VERIFY(jvmti->AddCapabilities(&caps))) {
240 return JNI_ERR;
241 }
242
243 memset(&callbacks, 0, sizeof(callbacks));
244 callbacks.Exception = &Exception;
245 if (!NSK_VERIFY(nsk_jvmti_init_MA(&callbacks)))
246 return JNI_ERR;
247
248 return JNI_OK;
249 }
250
251 /* ========================================================================== */
252
253 }
|