47 static jint testStep;
48 static int redefineNumber;
49 static jint newClassSize;
50 static unsigned char* newClassBytes;
51 static jthread testedThread;
52 static jclass testClass;
53 char chbuffer[255];
54
55 const char* getThreadName(JNIEnv* jni_env, jthread thread);
56 const char* getClassName(jvmtiEnv *jvmti_env, JNIEnv* jni_env, jobject object);
57 int readNewBytecode(jvmtiEnv* jvmti, int testcase);
58 int getLocalVariableValue(jvmtiEnv *jvmti_env, jthread thread, jmethodID method);
59
60 /* ============================================================================= */
61
62 void setCurrentStep(JNIEnv* jni_env, int value) {
63
64 jfieldID fld;
65
66 if (!NSK_JNI_VERIFY(jni_env, (fld =
67 NSK_CPP_STUB4(GetStaticFieldID, jni_env, testClass, "currentStep", "I")) != NULL)) {
68 NSK_CPP_STUB2(FatalError, jni_env,
69 "TEST FAILED: while getting currentStep fieldID\n");
70 }
71
72 if (!NSK_JNI_VERIFY_VOID(jni_env,
73 NSK_CPP_STUB4(SetStaticIntField, jni_env, testClass, fld, value))) {
74 NSK_CPP_STUB2(FatalError, jni_env,
75 "TEST FAILED: while setting value of currentStep fieldID\n");
76 }
77
78 }
79
80 /* ============================================================================= */
81
82 void enableEvent(jvmtiEnv *jvmti_env, jvmtiEvent event, jthread thread) {
83
84 if (!NSK_JVMTI_VERIFY(
85 NSK_CPP_STUB4(SetEventNotificationMode, jvmti_env, JVMTI_ENABLE,
86 event, thread))) {
87 NSK_COMPLAIN1("TEST FAILED: enabling %s\n", TranslateEvent(event));
88 nsk_jvmti_setFailStatus();
89 }
90 }
91
92 /* ============================================================================= */
93
94 void disableEvent(jvmtiEnv *jvmti_env, jvmtiEvent event, jthread thread) {
95
96 if (!NSK_JVMTI_VERIFY(
97 NSK_CPP_STUB4(SetEventNotificationMode, jvmti_env, JVMTI_DISABLE,
98 event, thread))) {
99 NSK_COMPLAIN1("TEST FAILED: disabling %s\n", TranslateEvent(event));
100 nsk_jvmti_setFailStatus();
101 }
102 }
103
104 /* ============================================================================= */
105
106 void redefineClass(jvmtiEnv *jvmti_env, jclass klass) {
107
108 jvmtiClassDefinition classDef;
109
110 char *className;
111
112 if (!NSK_JVMTI_VERIFY(
113 NSK_CPP_STUB4(GetClassSignature, jvmti_env, klass,
114 &className, NULL))) {
115 nsk_jvmti_setFailStatus();
116 return;
117 }
118
119 if (!NSK_VERIFY(readNewBytecode(jvmti_env, redefineNumber++))) {
120 NSK_COMPLAIN0("TEST FAILED: new bytecode could not be read\n");
121 nsk_jvmti_setFailStatus();
122 return;
123 }
124
125 classDef.klass = klass;
126 classDef.class_byte_count = newClassSize;
127 classDef.class_bytes = newClassBytes;
128
129 NSK_DISPLAY1("\tredefining class %s\n", className);
130 if (!NSK_JVMTI_VERIFY(
131 NSK_CPP_STUB3(RedefineClasses, jvmti_env, 1, &classDef))) {
132 NSK_COMPLAIN1("TEST FAILED: while redefining class %s\n", className);
133 nsk_jvmti_setFailStatus();
134 return;
135 }
136
137 if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB2(Deallocate,
138 jvmti_env, (unsigned char*)className))) {
139 nsk_jvmti_setFailStatus();
140 }
141
142 }
143
144 /* ============================================================================= */
145
146 /** Agent algorithm. */
147 static void JNICALL
148 agentProc(jvmtiEnv* jvmti, JNIEnv* agentJNI, void* arg) {
149
150 redefineNumber = 1;
151 jni = agentJNI;
152
153 NSK_DISPLAY0("Waiting for debuggee to become ready\n");
154 if (!nsk_jvmti_waitForSync(timeout))
155 return;
156
157 testStep = 1;
158 NSK_DISPLAY0("\n\n>>>> Debugge started, waiting for class loading \n");
159 if (!nsk_jvmti_resumeSync())
160 return;
161
162 NSK_DISPLAY0("Waiting for debuggee's threads to finish\n");
163 if (!nsk_jvmti_waitForSync(timeout))
164 return;
165
166 NSK_TRACE(NSK_CPP_STUB2(DeleteGlobalRef, jni, testClass));
167 NSK_TRACE(NSK_CPP_STUB2(DeleteGlobalRef, jni, testedThread));
168
169 NSK_DISPLAY0("Let debuggee to finish\n");
170 if (!nsk_jvmti_resumeSync())
171 return;
172 }
173
174 /* ============================================================================= */
175
176 void setBreakPoint(jvmtiEnv *jvmti_env, JNIEnv *jni_env, jclass klass) {
177 jmethodID mid;
178
179 if (!NSK_JNI_VERIFY(jni_env, (mid = NSK_CPP_STUB4(GetMethodID,
180 jni_env, klass, METHOD_NAME, METHOD_SIG)) != NULL))
181 NSK_CPP_STUB2(FatalError, jni_env,
182 "[agent] failed to get ID for the java method\n");
183
184 if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB3(SetBreakpoint,
185 jvmti_env, mid, 1)))
186 NSK_CPP_STUB2(FatalError, jni_env,
187 "[agent] failed to set breakpoint\n");
188 }
189
190 /* ============================================================================= */
191
192 /**
193 * CLASS_LOAD callback.
194 * -
195 */
196 JNIEXPORT void JNICALL
197 callbackClassLoad(jvmtiEnv *jvmti_env, JNIEnv* jni_env, jthread thread,
198 jclass klass) {
199
200 char *className;
201 char *generic;
202
203 if (!NSK_JVMTI_VERIFY(
204 NSK_CPP_STUB4(GetClassSignature, jvmti_env, klass,
205 &className, &generic))) {
206 nsk_jvmti_setFailStatus();
207 return;
208 }
209
210 if (strcmp(className, EXPECTED_CLASS_SIGN)
211 == 0) {
212
213 NSK_DISPLAY1("\n\n>>>> Class loaded: %s", className);
214 NSK_DISPLAY0(", activating breakpoint\n");
215 setBreakPoint(jvmti_env, jni_env, klass);
216 }
217
218 if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB2(Deallocate,
219 jvmti_env, (unsigned char*)className))) {
220 nsk_jvmti_setFailStatus();
221 }
222
223 if (generic != NULL)
224 if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB2(Deallocate,
225 jvmti_env, (unsigned char*)generic))) {
226 nsk_jvmti_setFailStatus();
227 }
228 }
229
230 /* ============================================================================= */
231
232 /**
233 * BREAKPOINT callback.
234 * -
235 */
236 JNIEXPORT void JNICALL
237 callbackBreakpoint(jvmtiEnv *jvmti_env, JNIEnv* jni_env, jthread thread,
238 jmethodID method, jlocation location) {
239
240 NSK_DISPLAY0("\n\n>>>>Breakpoint fired, enabling SINGLE_STEP\n");
241 enableEvent(jvmti_env, JVMTI_EVENT_SINGLE_STEP, thread);
242 }
243
244 /* ============================================================================= */
245
246 /**
247 * BREAKPOINT callback.
248 * -
249 */
250 JNIEXPORT void JNICALL
251 callbackSingleStep(jvmtiEnv *jvmti_env, JNIEnv* jni_env, jthread thread,
252 jmethodID method, jlocation location) {
253
254 char *methodName;
255
256 if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB5(GetMethodName,
257 jvmti_env, method, &methodName, NULL, NULL))) {
258 NSK_COMPLAIN0("TEST FAILED: unable to get method name during Breakpoint callback\n\n");
259 }
260
261 if (strcmp(methodName, METHOD_NAME) == 0) {
262 char *declaringClassName;
263 jclass declaringClass;
264
265 if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB3(GetMethodDeclaringClass,
266 jvmti_env, method, &declaringClass))) {
267 NSK_COMPLAIN0("TEST FAILED: unable to get method name during Breakpoint callback\n\n");
268 }
269
270 if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB4(GetClassSignature,
271 jvmti_env, declaringClass, &declaringClassName, NULL))) {
272 NSK_COMPLAIN0("TEST FAILED: unable to get method name during Breakpoint callback\n\n");
273 }
274
275 if (strcmp(declaringClassName, EXPECTED_CLASS_SIGN) == 0) {
276 int value;
277 jboolean is_obsolete;
278
279 /* getting local variable table*/
280 value = getLocalVariableValue(jvmti_env, thread, method);
281
282 switch (testStep) {
283 case 1:
284
285 if (value == 1) {
286 redefineClass(jvmti_env, declaringClass);
287 testStep++;
288 }
289 break;
290
291 case 2:
292
293 NSK_DISPLAY1("\n\n>>>> Checking if redefined method is obsolete\n", testStep);
294
295 if (!NSK_JVMTI_VERIFY(
296 NSK_CPP_STUB3(IsMethodObsolete, jvmti, method, &is_obsolete))) {
297 NSK_COMPLAIN0("TEST FAILED: unable to check method to be obsolete\n");
298 nsk_jvmti_setFailStatus();
299 return;
300 }
301
302 if (!is_obsolete) {
303 NSK_COMPLAIN0("TEST FAILED: method must be obsolete\n");
304 nsk_jvmti_setFailStatus();
305 }
306 testStep++;
307 break;
308
309 case 3:
310
311 NSK_DISPLAY1("\n\n>>>> Popping the currently executing frame\n", testStep);
312 testStep++;
313 setCurrentStep(jni_env, testStep);
314
315 break;
316
317 case 5:
318
319 if (value > 10 && value < 1000) {
320 NSK_DISPLAY1("\n\n>>>> Disabling single step\n", testStep);
321 disableEvent(jvmti_env, JVMTI_EVENT_SINGLE_STEP, thread);
322 setCurrentStep(jni_env, testStep);
323 }
324
325 } /* case */
326
327 }
328
329 if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB2(Deallocate,
330 jvmti_env, (unsigned char*) declaringClassName))) {
331 NSK_COMPLAIN0("TEST FAILED: unable to deallocate memory pointed to method name\n\n");
332 }
333
334 }
335
336 if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB2(Deallocate,
337 jvmti_env, (unsigned char*) methodName))) {
338 NSK_COMPLAIN0("TEST FAILED: unable to deallocate memory pointed to method name\n\n");
339 }
340
341 }
342
343 /* ============================================================================= */
344
345 /**
346 * EXCEPTION callback.
347 * -
348 */
349 JNIEXPORT void JNICALL
350 callbackException(jvmtiEnv *jvmti_env, JNIEnv* jni_env, jthread thread,
351 jmethodID method, jlocation location, jobject exception,
352 jmethodID catch_method, jlocation catch_location) {
353
354 const char *className;
355
356 className = getClassName(jvmti_env, jni_env, exception);
357
358 if (strcmp(EXPECTED_CLASS_SIGN, className) == 0) {
359 jclass klass;
360
361 NSK_DISPLAY2("\n\n>>>> Exception %s in thread - %s\n",
362 className, getThreadName(jni_env, thread));
363
364 testStep++;
365 if (!NSK_JNI_VERIFY(jni_env, (klass =
366 NSK_CPP_STUB2(GetObjectClass, jni_env, exception)) != NULL)) {
367 nsk_jvmti_setFailStatus();
368 return;
369 }
370
371 redefineClass(jvmti_env, klass);
372 }
373 }
374
375 /* ============================================================================= */
376
377 /**
378 * EXCEPTION_CATCH callback.
379 * -
380 */
381 JNIEXPORT void JNICALL
382 callbackExceptionCatch(jvmtiEnv *jvmti_env, JNIEnv* jni_env, jthread thread,
383 jmethodID method, jlocation location,
384 jobject exception) {
385
386 const char *className;
387
388 className = getClassName(jvmti_env, jni_env, exception);
389
390 if (strcmp(EXPECTED_CLASS_SIGN, className) == 0) {
391 jclass klass;
392
393 NSK_DISPLAY2("\n\n>>>> Caught exception %s in thread - %s\n",
394 className, getThreadName(jni_env, thread));
395
396 testStep++;
397 if (!NSK_JNI_VERIFY(jni_env, (klass =
398 NSK_CPP_STUB2(GetObjectClass, jni_env, exception)) != NULL)) {
399 nsk_jvmti_setFailStatus();
400 return;
401 }
402
403 redefineClass(jvmti_env, klass);
404 }
405 }
406
407 /* ============================================================================= */
408
409 int readNewBytecode(jvmtiEnv* jvmti, int testcase) {
410
411 char filename[256];
412 FILE *bytecode;
413 const char *pathToByteCode = nsk_jvmti_findOptionValue(PATH_TO_NEW_BYTECODE);
414 jint read_bytes;
415
416
417 if (!pathToByteCode) {
418 NSK_COMPLAIN0("TEST FAILED: error opening file\n");
419 return NSK_FALSE;
420 }
421
422 sprintf(filename,"%s/%s%02d/%s.class",
423 pathToByteCode, "newclass", testcase, EXPECTED_CLASS_NAME);
424
425 NSK_DISPLAY1("\treading new bytecode for the tested class\n\tfile name: %s\n",
426 filename);
427
428 bytecode = fopen(filename, "rb");
429 if (bytecode == NULL) {
430 NSK_COMPLAIN0("TEST FAILED: error opening file\n");
431 return NSK_FALSE;
432 }
433
434 fseek(bytecode, 0, SEEK_END);
435 newClassSize = ftell(bytecode);
436 rewind(bytecode);
437
438 if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB3(Allocate, jvmti,
439 newClassSize, &newClassBytes))) {
440 NSK_COMPLAIN0("buffer couldn't be allocated\n");
441 return NSK_FALSE;
442 }
443 read_bytes = (jint) fread(newClassBytes, 1, newClassSize, bytecode);
444 fclose(bytecode);
445 if (read_bytes != newClassSize) {
446 NSK_COMPLAIN0("TEST FAILED: error reading file\n");
447 return NSK_FALSE;
448 }
449
450 return NSK_TRUE;
451 }
452
453 /* ============================================================================= */
454
455 const char* getThreadName(JNIEnv* jni_env, jthread thread) {
456 jmethodID methodID;
457 jclass klass;
458 jstring jthreadName;
459 const char *threadName;
460
461 strcpy(chbuffer, "");
462
463 if (!NSK_JNI_VERIFY(jni_env, (klass =
464 NSK_CPP_STUB2(GetObjectClass, jni_env, thread)) != NULL)) {
465 nsk_jvmti_setFailStatus();
466 return chbuffer;
467 }
468
469 if (!NSK_JNI_VERIFY(jni_env, (methodID =
470 NSK_CPP_STUB4(GetMethodID, jni_env, klass,
471 "getName", "()Ljava/lang/String;")) != NULL)) {
472 nsk_jvmti_setFailStatus();
473 return chbuffer;
474 }
475
476 jthreadName = (jstring) NSK_CPP_STUB3(CallObjectMethod, jni_env, thread,
477 methodID);
478
479 threadName = NSK_CPP_STUB3(GetStringUTFChars, jni_env, jthreadName, 0);
480
481 strcpy(chbuffer, threadName);
482
483 NSK_CPP_STUB3(ReleaseStringUTFChars, jni_env, jthreadName, threadName);
484
485 return chbuffer;
486 }
487
488 /* ============================================================================= */
489
490 const char* getClassName(jvmtiEnv *jvmti_env, JNIEnv* jni_env, jobject object) {
491
492 char *className;
493 char *generic;
494 jclass klass;
495
496 strcpy(chbuffer, "");
497
498 if (!NSK_JNI_VERIFY(jni_env, (klass =
499 NSK_CPP_STUB2(GetObjectClass, jni_env, object)) != NULL)) {
500 nsk_jvmti_setFailStatus();
501 return chbuffer;
502 }
503
504 if (!NSK_JVMTI_VERIFY(
505 NSK_CPP_STUB4(GetClassSignature, jvmti_env, klass,
506 &className, &generic))) {
507 nsk_jvmti_setFailStatus();
508 return chbuffer;
509 }
510
511 strcpy(chbuffer, className);
512
513 if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB2(Deallocate,
514 jvmti_env, (unsigned char*)className))) {
515 nsk_jvmti_setFailStatus();
516 }
517
518 if (generic != NULL)
519 if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB2(Deallocate,
520 jvmti_env, (unsigned char*)generic))) {
521 nsk_jvmti_setFailStatus();
522 }
523
524 return chbuffer;
525 }
526
527 /* ============================================================================= */
528
529 int getLocalVariableValue(jvmtiEnv *jvmti_env, jthread thread,
530 jmethodID method) {
531
532 jvmtiLocalVariableEntry *table = NULL;
533 jint entryCount = 0;
534 int i;
535 jint value = -1;
536
537 /* getting local variable table*/
538 if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB4(GetLocalVariableTable,
539 jvmti_env, method, &entryCount, &table))) {
540 NSK_COMPLAIN0("TEST FAILED: unable to get local variable table\n\n");
541 }
542
543 if (table != NULL) {
544 jvmtiError error;
545
546 for (i = 0; i < entryCount; i++) {
547 if (strcmp(table[i].name, LOCAL_VARIABLE_NAME) == 0) {
548 error = NSK_CPP_STUB5(GetLocalInt, jvmti_env, thread, 0,
549 table[i].slot, &value);
550 if (!NSK_VERIFY(error == JVMTI_ERROR_NONE
551 || error == JVMTI_ERROR_INVALID_SLOT))
552 NSK_COMPLAIN0("TEST FAILED: unable to get local variable table\n\n");
553 }
554 }
555
556 for (i = 0; i < entryCount; i++) {
557
558 if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB2(Deallocate,
559 jvmti_env, (unsigned char*)table[i].name))) {
560 NSK_COMPLAIN0("TEST FAILED: unable to deallocate memory pointed to method name\n\n");
561 }
562
563 if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB2(Deallocate,
564 jvmti_env, (unsigned char*)table[i].signature))) {
565 NSK_COMPLAIN0("TEST FAILED: unable to deallocate memory pointed to method signature\n\n");
566 }
567
568 }
569
570 if (!NSK_JVMTI_VERIFY(NSK_CPP_STUB2(Deallocate,
571 jvmti_env, (unsigned char*)table))) {
572 NSK_COMPLAIN0("TEST FAILED: unable to deallocate memory pointed to local variable table\n\n");
573 }
574
575 }
576
577 return value;
578 }
579
580 /* ============================================================================= */
581
582 JNIEXPORT void JNICALL
583 Java_nsk_jvmti_scenarios_hotswap_HS201_hs201t001_setThread(JNIEnv *env,
584 jclass cls, jthread thread) {
585
586 if (!NSK_JNI_VERIFY(env, (testClass = (jclass)
587 NSK_CPP_STUB2(NewGlobalRef, env, cls)) != NULL))
588 nsk_jvmti_setFailStatus();
589
590 if (!NSK_JNI_VERIFY(env, (testedThread =
591 NSK_CPP_STUB2(NewGlobalRef, env, thread)) != NULL))
592 nsk_jvmti_setFailStatus();
593
594 }
595
596 /* ============================================================================= */
597
598 JNIEXPORT jboolean JNICALL
599 Java_nsk_jvmti_scenarios_hotswap_HS201_hs201t001_resumeThread(JNIEnv *env,
600 jclass cls, jthread thread) {
601
602 NSK_DISPLAY0("\tresuming thread...\n");
603 disableEvent(jvmti, JVMTI_EVENT_SINGLE_STEP, thread);
604
605 if (!NSK_JVMTI_VERIFY(
606 NSK_CPP_STUB2(ResumeThread, jvmti, thread))) {
607 NSK_COMPLAIN0("TEST FAILED: unable to resume the thread\n");
608 nsk_jvmti_setFailStatus();
609 return JNI_FALSE;
610 }
611
612 return JNI_TRUE;
613 }
614
615 /* ============================================================================= */
616
617 JNIEXPORT jboolean JNICALL
618 Java_nsk_jvmti_scenarios_hotswap_HS201_hs201t001_suspendThread(JNIEnv *env,
619 jclass cls, jthread thread) {
620
621 NSK_DISPLAY0("\tsuspending thread...\n");
622 disableEvent(jvmti, JVMTI_EVENT_SINGLE_STEP, thread);
623
624 if (!NSK_JVMTI_VERIFY(
625 NSK_CPP_STUB2(SuspendThread, jvmti, thread))) {
626 NSK_COMPLAIN0("TEST FAILED: unable to suspend the thread\n");
627 nsk_jvmti_setFailStatus();
628 return JNI_FALSE;
629 }
630
631 return JNI_TRUE;
632 }
633
634 /* ============================================================================= */
635
636 JNIEXPORT jboolean JNICALL
637 Java_nsk_jvmti_scenarios_hotswap_HS201_hs201t001_popFrame(JNIEnv *env,
638 jclass cls, jthread thread) {
639
640 NSK_DISPLAY0("\tpopping frame...\n");
641 if (!NSK_JVMTI_VERIFY(
642 NSK_CPP_STUB2(PopFrame, jvmti, thread))) {
643 NSK_COMPLAIN0("TEST FAILED: unable to pop the currently executed frame\n");
644 nsk_jvmti_setFailStatus();
645 return JNI_FALSE;
646 }
647
648 NSK_DISPLAY0("\tresuming thread...\n");
649 if (!NSK_JVMTI_VERIFY(
650 NSK_CPP_STUB2(ResumeThread, jvmti, thread))) {
651 NSK_COMPLAIN0("TEST FAILED: unable to resume the thread\n");
652 nsk_jvmti_setFailStatus();
653 return NSK_FALSE;
654 }
655
656 testStep++;
657 enableEvent(jvmti, JVMTI_EVENT_SINGLE_STEP, thread);
658
659 return JNI_TRUE;
660 }
661
662 /* ============================================================================= */
663
664 /** Agent library initialization. */
665 #ifdef STATIC_BUILD
666 JNIEXPORT jint JNICALL Agent_OnLoad_hs201t001(JavaVM *jvm, char *options, void *reserved) {
667 return Agent_Initialize(jvm, options, reserved);
668 }
669 JNIEXPORT jint JNICALL Agent_OnAttach_hs201t001(JavaVM *jvm, char *options, void *reserved) {
670 return Agent_Initialize(jvm, options, reserved);
679 return JNI_ERR;
680
681 timeout = nsk_jvmti_getWaitTime() * 60 * 1000;
682
683 if (!NSK_VERIFY((jvmti =
684 nsk_jvmti_createJVMTIEnv(jvm, reserved)) != NULL))
685 return JNI_ERR;
686
687 {
688 jvmtiCapabilities caps;
689 memset(&caps, 0, sizeof(caps));
690
691 caps.can_generate_exception_events = 1;
692 caps.can_generate_breakpoint_events = 1;
693 caps.can_generate_single_step_events = 1;
694 caps.can_access_local_variables = 1;
695 caps.can_redefine_classes = 1;
696 caps.can_pop_frame = 1;
697 caps.can_suspend = 1;
698
699 if (!NSK_JVMTI_VERIFY(
700 NSK_CPP_STUB2(AddCapabilities, jvmti, &caps)))
701 return JNI_ERR;
702 }
703
704 {
705 jvmtiEventCallbacks eventCallbacks;
706 memset(&eventCallbacks, 0, sizeof(eventCallbacks));
707 eventCallbacks.ClassLoad = callbackClassLoad;
708 eventCallbacks.Exception = callbackException;
709 eventCallbacks.ExceptionCatch = callbackExceptionCatch;
710 eventCallbacks.Breakpoint = callbackBreakpoint;
711 eventCallbacks.SingleStep = callbackSingleStep;
712 if (!NSK_JVMTI_VERIFY(
713 NSK_CPP_STUB3(SetEventCallbacks, jvmti,
714 &eventCallbacks, sizeof(eventCallbacks))))
715 return JNI_ERR;
716 }
717
718 NSK_DISPLAY0("Enable events\n");
719
720 enableEvent(jvmti, JVMTI_EVENT_CLASS_LOAD, testedThread);
721 enableEvent(jvmti, JVMTI_EVENT_BREAKPOINT, testedThread);
722 enableEvent(jvmti, JVMTI_EVENT_EXCEPTION, testedThread);
723 enableEvent(jvmti, JVMTI_EVENT_EXCEPTION_CATCH, testedThread);
724
725 if (!NSK_VERIFY(nsk_jvmti_setAgentProc(agentProc, NULL)))
726 return JNI_ERR;
727
728 return JNI_OK;
729 }
730
731 /* ============================================================================= */
732
733 }
|
47 static jint testStep;
48 static int redefineNumber;
49 static jint newClassSize;
50 static unsigned char* newClassBytes;
51 static jthread testedThread;
52 static jclass testClass;
53 char chbuffer[255];
54
55 const char* getThreadName(JNIEnv* jni_env, jthread thread);
56 const char* getClassName(jvmtiEnv *jvmti_env, JNIEnv* jni_env, jobject object);
57 int readNewBytecode(jvmtiEnv* jvmti, int testcase);
58 int getLocalVariableValue(jvmtiEnv *jvmti_env, jthread thread, jmethodID method);
59
60 /* ============================================================================= */
61
62 void setCurrentStep(JNIEnv* jni_env, int value) {
63
64 jfieldID fld;
65
66 if (!NSK_JNI_VERIFY(jni_env, (fld =
67 jni_env->GetStaticFieldID(testClass, "currentStep", "I")) != NULL)) {
68 jni_env->FatalError("TEST FAILED: while getting currentStep fieldID\n");
69 }
70
71 if (!NSK_JNI_VERIFY_VOID(jni_env, jni_env->SetStaticIntField(testClass, fld, value))) {
72 jni_env->FatalError("TEST FAILED: while setting value of currentStep fieldID\n");
73 }
74
75 }
76
77 /* ============================================================================= */
78
79 void enableEvent(jvmtiEnv *jvmti_env, jvmtiEvent event, jthread thread) {
80
81 if (!NSK_JVMTI_VERIFY(jvmti_env->SetEventNotificationMode(JVMTI_ENABLE, event, thread))) {
82 NSK_COMPLAIN1("TEST FAILED: enabling %s\n", TranslateEvent(event));
83 nsk_jvmti_setFailStatus();
84 }
85 }
86
87 /* ============================================================================= */
88
89 void disableEvent(jvmtiEnv *jvmti_env, jvmtiEvent event, jthread thread) {
90
91 if (!NSK_JVMTI_VERIFY(jvmti_env->SetEventNotificationMode(JVMTI_DISABLE, event, thread))) {
92 NSK_COMPLAIN1("TEST FAILED: disabling %s\n", TranslateEvent(event));
93 nsk_jvmti_setFailStatus();
94 }
95 }
96
97 /* ============================================================================= */
98
99 void redefineClass(jvmtiEnv *jvmti_env, jclass klass) {
100
101 jvmtiClassDefinition classDef;
102
103 char *className;
104
105 if (!NSK_JVMTI_VERIFY(jvmti_env->GetClassSignature(klass, &className, NULL))) {
106 nsk_jvmti_setFailStatus();
107 return;
108 }
109
110 if (!NSK_VERIFY(readNewBytecode(jvmti_env, redefineNumber++))) {
111 NSK_COMPLAIN0("TEST FAILED: new bytecode could not be read\n");
112 nsk_jvmti_setFailStatus();
113 return;
114 }
115
116 classDef.klass = klass;
117 classDef.class_byte_count = newClassSize;
118 classDef.class_bytes = newClassBytes;
119
120 NSK_DISPLAY1("\tredefining class %s\n", className);
121 if (!NSK_JVMTI_VERIFY(jvmti_env->RedefineClasses(1, &classDef))) {
122 NSK_COMPLAIN1("TEST FAILED: while redefining class %s\n", className);
123 nsk_jvmti_setFailStatus();
124 return;
125 }
126
127 if (!NSK_JVMTI_VERIFY(jvmti_env->Deallocate((unsigned char*)className))) {
128 nsk_jvmti_setFailStatus();
129 }
130
131 }
132
133 /* ============================================================================= */
134
135 /** Agent algorithm. */
136 static void JNICALL
137 agentProc(jvmtiEnv* jvmti, JNIEnv* agentJNI, void* arg) {
138
139 redefineNumber = 1;
140 jni = agentJNI;
141
142 NSK_DISPLAY0("Waiting for debuggee to become ready\n");
143 if (!nsk_jvmti_waitForSync(timeout))
144 return;
145
146 testStep = 1;
147 NSK_DISPLAY0("\n\n>>>> Debugge started, waiting for class loading \n");
148 if (!nsk_jvmti_resumeSync())
149 return;
150
151 NSK_DISPLAY0("Waiting for debuggee's threads to finish\n");
152 if (!nsk_jvmti_waitForSync(timeout))
153 return;
154
155 NSK_TRACE(jni->DeleteGlobalRef(testClass));
156 NSK_TRACE(jni->DeleteGlobalRef(testedThread));
157
158 NSK_DISPLAY0("Let debuggee to finish\n");
159 if (!nsk_jvmti_resumeSync())
160 return;
161 }
162
163 /* ============================================================================= */
164
165 void setBreakPoint(jvmtiEnv *jvmti_env, JNIEnv *jni_env, jclass klass) {
166 jmethodID mid;
167
168 if (!NSK_JNI_VERIFY(jni_env, (mid = jni_env->GetMethodID(klass, METHOD_NAME, METHOD_SIG)) != NULL))
169 jni_env->FatalError("[agent] failed to get ID for the java method\n");
170
171 if (!NSK_JVMTI_VERIFY(jvmti_env->SetBreakpoint(mid, 1)))
172 jni_env->FatalError("[agent] failed to set breakpoint\n");
173 }
174
175 /* ============================================================================= */
176
177 /**
178 * CLASS_LOAD callback.
179 * -
180 */
181 JNIEXPORT void JNICALL
182 callbackClassLoad(jvmtiEnv *jvmti_env, JNIEnv* jni_env, jthread thread,
183 jclass klass) {
184
185 char *className;
186 char *generic;
187
188 if (!NSK_JVMTI_VERIFY(jvmti_env->GetClassSignature(klass, &className, &generic))) {
189 nsk_jvmti_setFailStatus();
190 return;
191 }
192
193 if (strcmp(className, EXPECTED_CLASS_SIGN)
194 == 0) {
195
196 NSK_DISPLAY1("\n\n>>>> Class loaded: %s", className);
197 NSK_DISPLAY0(", activating breakpoint\n");
198 setBreakPoint(jvmti_env, jni_env, klass);
199 }
200
201 if (!NSK_JVMTI_VERIFY(jvmti_env->Deallocate((unsigned char*)className))) {
202 nsk_jvmti_setFailStatus();
203 }
204
205 if (generic != NULL)
206 if (!NSK_JVMTI_VERIFY(jvmti_env->Deallocate((unsigned char*)generic))) {
207 nsk_jvmti_setFailStatus();
208 }
209 }
210
211 /* ============================================================================= */
212
213 /**
214 * BREAKPOINT callback.
215 * -
216 */
217 JNIEXPORT void JNICALL
218 callbackBreakpoint(jvmtiEnv *jvmti_env, JNIEnv* jni_env, jthread thread,
219 jmethodID method, jlocation location) {
220
221 NSK_DISPLAY0("\n\n>>>>Breakpoint fired, enabling SINGLE_STEP\n");
222 enableEvent(jvmti_env, JVMTI_EVENT_SINGLE_STEP, thread);
223 }
224
225 /* ============================================================================= */
226
227 /**
228 * BREAKPOINT callback.
229 * -
230 */
231 JNIEXPORT void JNICALL
232 callbackSingleStep(jvmtiEnv *jvmti_env, JNIEnv* jni_env, jthread thread,
233 jmethodID method, jlocation location) {
234
235 char *methodName;
236
237 if (!NSK_JVMTI_VERIFY(jvmti_env->GetMethodName(method, &methodName, NULL, NULL))) {
238 NSK_COMPLAIN0("TEST FAILED: unable to get method name during Breakpoint callback\n\n");
239 }
240
241 if (strcmp(methodName, METHOD_NAME) == 0) {
242 char *declaringClassName;
243 jclass declaringClass;
244
245 if (!NSK_JVMTI_VERIFY(jvmti_env->GetMethodDeclaringClass(method, &declaringClass))) {
246 NSK_COMPLAIN0("TEST FAILED: unable to get method name during Breakpoint callback\n\n");
247 }
248
249 if (!NSK_JVMTI_VERIFY(jvmti_env->GetClassSignature(declaringClass, &declaringClassName, NULL))) {
250 NSK_COMPLAIN0("TEST FAILED: unable to get method name during Breakpoint callback\n\n");
251 }
252
253 if (strcmp(declaringClassName, EXPECTED_CLASS_SIGN) == 0) {
254 int value;
255 jboolean is_obsolete;
256
257 /* getting local variable table*/
258 value = getLocalVariableValue(jvmti_env, thread, method);
259
260 switch (testStep) {
261 case 1:
262
263 if (value == 1) {
264 redefineClass(jvmti_env, declaringClass);
265 testStep++;
266 }
267 break;
268
269 case 2:
270
271 NSK_DISPLAY1("\n\n>>>> Checking if redefined method is obsolete\n", testStep);
272
273 if (!NSK_JVMTI_VERIFY(jvmti->IsMethodObsolete(method, &is_obsolete))) {
274 NSK_COMPLAIN0("TEST FAILED: unable to check method to be obsolete\n");
275 nsk_jvmti_setFailStatus();
276 return;
277 }
278
279 if (!is_obsolete) {
280 NSK_COMPLAIN0("TEST FAILED: method must be obsolete\n");
281 nsk_jvmti_setFailStatus();
282 }
283 testStep++;
284 break;
285
286 case 3:
287
288 NSK_DISPLAY1("\n\n>>>> Popping the currently executing frame\n", testStep);
289 testStep++;
290 setCurrentStep(jni_env, testStep);
291
292 break;
293
294 case 5:
295
296 if (value > 10 && value < 1000) {
297 NSK_DISPLAY1("\n\n>>>> Disabling single step\n", testStep);
298 disableEvent(jvmti_env, JVMTI_EVENT_SINGLE_STEP, thread);
299 setCurrentStep(jni_env, testStep);
300 }
301
302 } /* case */
303
304 }
305
306 if (!NSK_JVMTI_VERIFY(jvmti_env->Deallocate((unsigned char*) declaringClassName))) {
307 NSK_COMPLAIN0("TEST FAILED: unable to deallocate memory pointed to method name\n\n");
308 }
309
310 }
311
312 if (!NSK_JVMTI_VERIFY(jvmti_env->Deallocate((unsigned char*) methodName))) {
313 NSK_COMPLAIN0("TEST FAILED: unable to deallocate memory pointed to method name\n\n");
314 }
315
316 }
317
318 /* ============================================================================= */
319
320 /**
321 * EXCEPTION callback.
322 * -
323 */
324 JNIEXPORT void JNICALL
325 callbackException(jvmtiEnv *jvmti_env, JNIEnv* jni_env, jthread thread,
326 jmethodID method, jlocation location, jobject exception,
327 jmethodID catch_method, jlocation catch_location) {
328
329 const char *className;
330
331 className = getClassName(jvmti_env, jni_env, exception);
332
333 if (strcmp(EXPECTED_CLASS_SIGN, className) == 0) {
334 jclass klass;
335
336 NSK_DISPLAY2("\n\n>>>> Exception %s in thread - %s\n",
337 className, getThreadName(jni_env, thread));
338
339 testStep++;
340 if (!NSK_JNI_VERIFY(jni_env, (klass = jni_env->GetObjectClass(exception)) != NULL)) {
341 nsk_jvmti_setFailStatus();
342 return;
343 }
344
345 redefineClass(jvmti_env, klass);
346 }
347 }
348
349 /* ============================================================================= */
350
351 /**
352 * EXCEPTION_CATCH callback.
353 * -
354 */
355 JNIEXPORT void JNICALL
356 callbackExceptionCatch(jvmtiEnv *jvmti_env, JNIEnv* jni_env, jthread thread,
357 jmethodID method, jlocation location,
358 jobject exception) {
359
360 const char *className;
361
362 className = getClassName(jvmti_env, jni_env, exception);
363
364 if (strcmp(EXPECTED_CLASS_SIGN, className) == 0) {
365 jclass klass;
366
367 NSK_DISPLAY2("\n\n>>>> Caught exception %s in thread - %s\n",
368 className, getThreadName(jni_env, thread));
369
370 testStep++;
371 if (!NSK_JNI_VERIFY(jni_env, (klass = jni_env->GetObjectClass(exception)) != NULL)) {
372 nsk_jvmti_setFailStatus();
373 return;
374 }
375
376 redefineClass(jvmti_env, klass);
377 }
378 }
379
380 /* ============================================================================= */
381
382 int readNewBytecode(jvmtiEnv* jvmti, int testcase) {
383
384 char filename[256];
385 FILE *bytecode;
386 const char *pathToByteCode = nsk_jvmti_findOptionValue(PATH_TO_NEW_BYTECODE);
387 jint read_bytes;
388
389
390 if (!pathToByteCode) {
391 NSK_COMPLAIN0("TEST FAILED: error opening file\n");
392 return NSK_FALSE;
393 }
394
395 sprintf(filename,"%s/%s%02d/%s.class",
396 pathToByteCode, "newclass", testcase, EXPECTED_CLASS_NAME);
397
398 NSK_DISPLAY1("\treading new bytecode for the tested class\n\tfile name: %s\n",
399 filename);
400
401 bytecode = fopen(filename, "rb");
402 if (bytecode == NULL) {
403 NSK_COMPLAIN0("TEST FAILED: error opening file\n");
404 return NSK_FALSE;
405 }
406
407 fseek(bytecode, 0, SEEK_END);
408 newClassSize = ftell(bytecode);
409 rewind(bytecode);
410
411 if (!NSK_JVMTI_VERIFY(jvmti->Allocate(newClassSize, &newClassBytes))) {
412 NSK_COMPLAIN0("buffer couldn't be allocated\n");
413 return NSK_FALSE;
414 }
415 read_bytes = (jint) fread(newClassBytes, 1, newClassSize, bytecode);
416 fclose(bytecode);
417 if (read_bytes != newClassSize) {
418 NSK_COMPLAIN0("TEST FAILED: error reading file\n");
419 return NSK_FALSE;
420 }
421
422 return NSK_TRUE;
423 }
424
425 /* ============================================================================= */
426
427 const char* getThreadName(JNIEnv* jni_env, jthread thread) {
428 jmethodID methodID;
429 jclass klass;
430 jstring jthreadName;
431 const char *threadName;
432
433 strcpy(chbuffer, "");
434
435 if (!NSK_JNI_VERIFY(jni_env, (klass = jni_env->GetObjectClass(thread)) != NULL)) {
436 nsk_jvmti_setFailStatus();
437 return chbuffer;
438 }
439
440 if (!NSK_JNI_VERIFY(jni_env, (methodID =
441 jni_env->GetMethodID(klass, "getName", "()Ljava/lang/String;")) != NULL)) {
442 nsk_jvmti_setFailStatus();
443 return chbuffer;
444 }
445
446 jthreadName = (jstring) jni_env->CallObjectMethod(thread, methodID);
447
448 threadName = jni_env->GetStringUTFChars(jthreadName, 0);
449
450 strcpy(chbuffer, threadName);
451
452 jni_env->ReleaseStringUTFChars(jthreadName, threadName);
453
454 return chbuffer;
455 }
456
457 /* ============================================================================= */
458
459 const char* getClassName(jvmtiEnv *jvmti_env, JNIEnv* jni_env, jobject object) {
460
461 char *className;
462 char *generic;
463 jclass klass;
464
465 strcpy(chbuffer, "");
466
467 if (!NSK_JNI_VERIFY(jni_env, (klass = jni_env->GetObjectClass(object)) != NULL)) {
468 nsk_jvmti_setFailStatus();
469 return chbuffer;
470 }
471
472 if (!NSK_JVMTI_VERIFY(jvmti_env->GetClassSignature(klass, &className, &generic))) {
473 nsk_jvmti_setFailStatus();
474 return chbuffer;
475 }
476
477 strcpy(chbuffer, className);
478
479 if (!NSK_JVMTI_VERIFY(jvmti_env->Deallocate((unsigned char*)className))) {
480 nsk_jvmti_setFailStatus();
481 }
482
483 if (generic != NULL)
484 if (!NSK_JVMTI_VERIFY(jvmti_env->Deallocate((unsigned char*)generic))) {
485 nsk_jvmti_setFailStatus();
486 }
487
488 return chbuffer;
489 }
490
491 /* ============================================================================= */
492
493 int getLocalVariableValue(jvmtiEnv *jvmti_env, jthread thread,
494 jmethodID method) {
495
496 jvmtiLocalVariableEntry *table = NULL;
497 jint entryCount = 0;
498 int i;
499 jint value = -1;
500
501 /* getting local variable table*/
502 if (!NSK_JVMTI_VERIFY(jvmti_env->GetLocalVariableTable(method, &entryCount, &table))) {
503 NSK_COMPLAIN0("TEST FAILED: unable to get local variable table\n\n");
504 }
505
506 if (table != NULL) {
507 jvmtiError error;
508
509 for (i = 0; i < entryCount; i++) {
510 if (strcmp(table[i].name, LOCAL_VARIABLE_NAME) == 0) {
511 error = jvmti_env->GetLocalInt(thread, 0, table[i].slot, &value);
512 if (!NSK_VERIFY(error == JVMTI_ERROR_NONE
513 || error == JVMTI_ERROR_INVALID_SLOT))
514 NSK_COMPLAIN0("TEST FAILED: unable to get local variable table\n\n");
515 }
516 }
517
518 for (i = 0; i < entryCount; i++) {
519
520 if (!NSK_JVMTI_VERIFY(jvmti_env->Deallocate((unsigned char*)table[i].name))) {
521 NSK_COMPLAIN0("TEST FAILED: unable to deallocate memory pointed to method name\n\n");
522 }
523
524 if (!NSK_JVMTI_VERIFY(jvmti_env->Deallocate((unsigned char*)table[i].signature))) {
525 NSK_COMPLAIN0("TEST FAILED: unable to deallocate memory pointed to method signature\n\n");
526 }
527
528 }
529
530 if (!NSK_JVMTI_VERIFY(jvmti_env->Deallocate((unsigned char*)table))) {
531 NSK_COMPLAIN0("TEST FAILED: unable to deallocate memory pointed to local variable table\n\n");
532 }
533
534 }
535
536 return value;
537 }
538
539 /* ============================================================================= */
540
541 JNIEXPORT void JNICALL
542 Java_nsk_jvmti_scenarios_hotswap_HS201_hs201t001_setThread(JNIEnv *env,
543 jclass cls, jthread thread) {
544
545 if (!NSK_JNI_VERIFY(env, (testClass = (jclass) env->NewGlobalRef(cls)) != NULL))
546 nsk_jvmti_setFailStatus();
547
548 if (!NSK_JNI_VERIFY(env, (testedThread = env->NewGlobalRef(thread)) != NULL))
549 nsk_jvmti_setFailStatus();
550
551 }
552
553 /* ============================================================================= */
554
555 JNIEXPORT jboolean JNICALL
556 Java_nsk_jvmti_scenarios_hotswap_HS201_hs201t001_resumeThread(JNIEnv *env,
557 jclass cls, jthread thread) {
558
559 NSK_DISPLAY0("\tresuming thread...\n");
560 disableEvent(jvmti, JVMTI_EVENT_SINGLE_STEP, thread);
561
562 if (!NSK_JVMTI_VERIFY(jvmti->ResumeThread(thread))) {
563 NSK_COMPLAIN0("TEST FAILED: unable to resume the thread\n");
564 nsk_jvmti_setFailStatus();
565 return JNI_FALSE;
566 }
567
568 return JNI_TRUE;
569 }
570
571 /* ============================================================================= */
572
573 JNIEXPORT jboolean JNICALL
574 Java_nsk_jvmti_scenarios_hotswap_HS201_hs201t001_suspendThread(JNIEnv *env,
575 jclass cls, jthread thread) {
576
577 NSK_DISPLAY0("\tsuspending thread...\n");
578 disableEvent(jvmti, JVMTI_EVENT_SINGLE_STEP, thread);
579
580 if (!NSK_JVMTI_VERIFY(jvmti->SuspendThread(thread))) {
581 NSK_COMPLAIN0("TEST FAILED: unable to suspend the thread\n");
582 nsk_jvmti_setFailStatus();
583 return JNI_FALSE;
584 }
585
586 return JNI_TRUE;
587 }
588
589 /* ============================================================================= */
590
591 JNIEXPORT jboolean JNICALL
592 Java_nsk_jvmti_scenarios_hotswap_HS201_hs201t001_popFrame(JNIEnv *env,
593 jclass cls, jthread thread) {
594
595 NSK_DISPLAY0("\tpopping frame...\n");
596 if (!NSK_JVMTI_VERIFY(jvmti->PopFrame(thread))) {
597 NSK_COMPLAIN0("TEST FAILED: unable to pop the currently executed frame\n");
598 nsk_jvmti_setFailStatus();
599 return JNI_FALSE;
600 }
601
602 NSK_DISPLAY0("\tresuming thread...\n");
603 if (!NSK_JVMTI_VERIFY(jvmti->ResumeThread(thread))) {
604 NSK_COMPLAIN0("TEST FAILED: unable to resume the thread\n");
605 nsk_jvmti_setFailStatus();
606 return NSK_FALSE;
607 }
608
609 testStep++;
610 enableEvent(jvmti, JVMTI_EVENT_SINGLE_STEP, thread);
611
612 return JNI_TRUE;
613 }
614
615 /* ============================================================================= */
616
617 /** Agent library initialization. */
618 #ifdef STATIC_BUILD
619 JNIEXPORT jint JNICALL Agent_OnLoad_hs201t001(JavaVM *jvm, char *options, void *reserved) {
620 return Agent_Initialize(jvm, options, reserved);
621 }
622 JNIEXPORT jint JNICALL Agent_OnAttach_hs201t001(JavaVM *jvm, char *options, void *reserved) {
623 return Agent_Initialize(jvm, options, reserved);
632 return JNI_ERR;
633
634 timeout = nsk_jvmti_getWaitTime() * 60 * 1000;
635
636 if (!NSK_VERIFY((jvmti =
637 nsk_jvmti_createJVMTIEnv(jvm, reserved)) != NULL))
638 return JNI_ERR;
639
640 {
641 jvmtiCapabilities caps;
642 memset(&caps, 0, sizeof(caps));
643
644 caps.can_generate_exception_events = 1;
645 caps.can_generate_breakpoint_events = 1;
646 caps.can_generate_single_step_events = 1;
647 caps.can_access_local_variables = 1;
648 caps.can_redefine_classes = 1;
649 caps.can_pop_frame = 1;
650 caps.can_suspend = 1;
651
652 if (!NSK_JVMTI_VERIFY(jvmti->AddCapabilities(&caps)))
653 return JNI_ERR;
654 }
655
656 {
657 jvmtiEventCallbacks eventCallbacks;
658 memset(&eventCallbacks, 0, sizeof(eventCallbacks));
659 eventCallbacks.ClassLoad = callbackClassLoad;
660 eventCallbacks.Exception = callbackException;
661 eventCallbacks.ExceptionCatch = callbackExceptionCatch;
662 eventCallbacks.Breakpoint = callbackBreakpoint;
663 eventCallbacks.SingleStep = callbackSingleStep;
664 if (!NSK_JVMTI_VERIFY(jvmti->SetEventCallbacks(&eventCallbacks, sizeof(eventCallbacks))))
665 return JNI_ERR;
666 }
667
668 NSK_DISPLAY0("Enable events\n");
669
670 enableEvent(jvmti, JVMTI_EVENT_CLASS_LOAD, testedThread);
671 enableEvent(jvmti, JVMTI_EVENT_BREAKPOINT, testedThread);
672 enableEvent(jvmti, JVMTI_EVENT_EXCEPTION, testedThread);
673 enableEvent(jvmti, JVMTI_EVENT_EXCEPTION_CATCH, testedThread);
674
675 if (!NSK_VERIFY(nsk_jvmti_setAgentProc(agentProc, NULL)))
676 return JNI_ERR;
677
678 return JNI_OK;
679 }
680
681 /* ============================================================================= */
682
683 }
|