< prev index next >

src/jdk.jdwp.agent/share/native/libjdwp/eventHelper.c

Print this page




 267     return command;
 268 }
 269 
 270 void eventHelper_holdEvents(void)
 271 {
 272     debugMonitorEnter(commandQueueLock);
 273     holdEvents = JNI_TRUE;
 274     debugMonitorNotifyAll(commandQueueLock);
 275     debugMonitorExit(commandQueueLock);
 276 }
 277 
 278 void eventHelper_releaseEvents(void)
 279 {
 280     debugMonitorEnter(commandQueueLock);
 281     holdEvents = JNI_FALSE;
 282     debugMonitorNotifyAll(commandQueueLock);
 283     debugMonitorExit(commandQueueLock);
 284 }
 285 
 286 static void












 287 writeSingleStepEvent(JNIEnv *env, PacketOutputStream *out, EventInfo *evinfo)
 288 {
 289     (void)outStream_writeObjectRef(env, out, evinfo->thread);
 290     writeCodeLocation(out, evinfo->clazz, evinfo->method, evinfo->location);
 291 }
 292 
 293 static void
 294 writeBreakpointEvent(JNIEnv *env, PacketOutputStream *out, EventInfo *evinfo)
 295 {
 296     (void)outStream_writeObjectRef(env, out, evinfo->thread);
 297     writeCodeLocation(out, evinfo->clazz, evinfo->method, evinfo->location);
 298 }
 299 
 300 static void
 301 writeFieldAccessEvent(JNIEnv *env, PacketOutputStream *out, EventInfo *evinfo)
 302 {
 303     jbyte fieldClassTag;
 304 
 305     fieldClassTag = referenceTypeTag(evinfo->u.field_access.field_clazz);
 306 
 307     (void)outStream_writeObjectRef(env, out, evinfo->thread);
 308     writeCodeLocation(out, evinfo->clazz, evinfo->method, evinfo->location);
 309     (void)outStream_writeByte(out, fieldClassTag);
 310     (void)outStream_writeObjectRef(env, out, evinfo->u.field_access.field_clazz);
 311     (void)outStream_writeFieldID(out, evinfo->u.field_access.field);
 312     (void)outStream_writeObjectTag(env, out, evinfo->object);
 313     (void)outStream_writeObjectRef(env, out, evinfo->object);
 314 }
 315 
 316 static void
 317 writeFieldModificationEvent(JNIEnv *env, PacketOutputStream *out,
 318                             EventInfo *evinfo)
 319 {
 320     jbyte fieldClassTag;
 321 
 322     fieldClassTag = referenceTypeTag(evinfo->u.field_modification.field_clazz);
 323 
 324     (void)outStream_writeObjectRef(env, out, evinfo->thread);
 325     writeCodeLocation(out, evinfo->clazz, evinfo->method, evinfo->location);
 326     (void)outStream_writeByte(out, fieldClassTag);
 327     (void)outStream_writeObjectRef(env, out, evinfo->u.field_modification.field_clazz);
 328     (void)outStream_writeFieldID(out, evinfo->u.field_modification.field);
 329     (void)outStream_writeObjectTag(env, out, evinfo->object);
 330     (void)outStream_writeObjectRef(env, out, evinfo->object);
 331     (void)outStream_writeValue(env, out, (jbyte)evinfo->u.field_modification.signature_type,
 332                          evinfo->u.field_modification.new_value);
 333 }
 334 
 335 static void
 336 writeExceptionEvent(JNIEnv *env, PacketOutputStream *out, EventInfo *evinfo)
 337 {
 338     (void)outStream_writeObjectRef(env, out, evinfo->thread);
 339     writeCodeLocation(out, evinfo->clazz, evinfo->method, evinfo->location);
 340     (void)outStream_writeObjectTag(env, out, evinfo->object);
 341     (void)outStream_writeObjectRef(env, out, evinfo->object);
 342     writeCodeLocation(out, evinfo->u.exception.catch_clazz,
 343                       evinfo->u.exception.catch_method, evinfo->u.exception.catch_location);
 344 }
 345 
 346 static void
 347 writeThreadEvent(JNIEnv *env, PacketOutputStream *out, EventInfo *evinfo)
 348 {
 349     (void)outStream_writeObjectRef(env, out, evinfo->thread);
 350 }
 351 
 352 static void
 353 writeMonitorEvent(JNIEnv *env, PacketOutputStream *out, EventInfo *evinfo)
 354 {
 355     jclass klass;
 356     (void)outStream_writeObjectRef(env, out, evinfo->thread);
 357     (void)outStream_writeObjectTag(env, out, evinfo->object);
 358     (void)outStream_writeObjectRef(env, out, evinfo->object);
 359     if (evinfo->ei == EI_MONITOR_WAIT || evinfo->ei == EI_MONITOR_WAITED) {
 360         /* clazz of evinfo was set to class of monitor object for monitor wait event class filtering.
 361          * So get the method class to write location info.
 362          * See cbMonitorWait() and cbMonitorWaited() function in eventHandler.c.
 363          */
 364         klass=getMethodClass(gdata->jvmti, evinfo->method);
 365         writeCodeLocation(out, klass, evinfo->method, evinfo->location);
 366         if (evinfo->ei == EI_MONITOR_WAIT) {
 367             (void)outStream_writeLong(out, evinfo->u.monitor.timeout);
 368         } else  if (evinfo->ei == EI_MONITOR_WAITED) {
 369             (void)outStream_writeBoolean(out, evinfo->u.monitor.timed_out);
 370         }
 371         /* This runs in a command loop and this thread may not return to java.
 372          * So we need to delete the local ref created by jvmti GetMethodDeclaringClass.
 373          */
 374         JNI_FUNC_PTR(env,DeleteLocalRef)(env, klass);
 375     } else {
 376         writeCodeLocation(out, evinfo->clazz, evinfo->method, evinfo->location);
 377     }
 378 }
 379 
 380 static void
 381 writeClassEvent(JNIEnv *env, PacketOutputStream *out, EventInfo *evinfo)
 382 {
 383     jbyte classTag;
 384     jint status;
 385     char *signature = NULL;
 386     jvmtiError error;
 387 
 388     classTag = referenceTypeTag(evinfo->clazz);
 389     error = classSignature(evinfo->clazz, &signature, NULL);
 390     if (error != JVMTI_ERROR_NONE) {
 391         EXIT_ERROR(error,"signature");
 392     }
 393     status = classStatus(evinfo->clazz);
 394 
 395     (void)outStream_writeObjectRef(env, out, evinfo->thread);
 396     (void)outStream_writeByte(out, classTag);
 397     (void)outStream_writeObjectRef(env, out, evinfo->clazz);
 398     (void)outStream_writeString(out, signature);
 399     (void)outStream_writeInt(out, map2jdwpClassStatus(status));
 400     jvmtiDeallocate(signature);
 401 }
 402 
 403 static void
 404 writeVMDeathEvent(JNIEnv *env, PacketOutputStream *out, EventInfo *evinfo)
 405 {
 406 }
 407 
 408 static void
 409 handleEventCommandSingle(JNIEnv *env, PacketOutputStream *out,
 410                            EventCommandSingle *command)
 411 {
 412     EventInfo *evinfo = &command->info;
 413 
 414     (void)outStream_writeByte(out, eventIndex2jdwp(evinfo->ei));
 415     (void)outStream_writeInt(out, command->id);


 417     switch (evinfo->ei) {
 418         case EI_SINGLE_STEP:
 419             writeSingleStepEvent(env, out, evinfo);
 420             break;
 421         case EI_BREAKPOINT:
 422             writeBreakpointEvent(env, out, evinfo);
 423             break;
 424         case EI_FIELD_ACCESS:
 425             writeFieldAccessEvent(env, out, evinfo);
 426             break;
 427         case EI_FIELD_MODIFICATION:
 428             writeFieldModificationEvent(env, out, evinfo);
 429             break;
 430         case EI_EXCEPTION:
 431             writeExceptionEvent(env, out, evinfo);
 432             break;
 433         case EI_THREAD_START:
 434         case EI_THREAD_END:
 435             writeThreadEvent(env, out, evinfo);
 436             break;













 437         case EI_CLASS_LOAD:
 438         case EI_CLASS_PREPARE:
 439             writeClassEvent(env, out, evinfo);
 440             break;
 441         case EI_MONITOR_CONTENDED_ENTER:
 442         case EI_MONITOR_CONTENDED_ENTERED:
 443         case EI_MONITOR_WAIT:
 444         case EI_MONITOR_WAITED:
 445             writeMonitorEvent(env, out, evinfo);
 446             break;
 447         case EI_VM_DEATH:
 448             writeVMDeathEvent(env, out, evinfo);
 449             break;
 450         default:
 451             EXIT_ERROR(AGENT_ERROR_INVALID_EVENT_TYPE,"unknown event index");
 452             break;
 453     }
 454     tossEventInfoRefs(env, evinfo);
 455 }
 456 


 797         return;
 798     }
 799     if (commandLoopEnteredVmDeathLock == JNI_TRUE) {
 800         debugMonitorExit(vmDeathLock);
 801         commandLoopEnteredVmDeathLock = JNI_FALSE;
 802     }
 803 }
 804 
 805 void
 806 commandLoop_sync(void)
 807 {
 808     debugMonitorEnter(vmDeathLock);
 809     debugMonitorExit(vmDeathLock);
 810 }
 811 
 812 /* Change all references to global in the EventInfo struct */
 813 static void
 814 saveEventInfoRefs(JNIEnv *env, EventInfo *evinfo)
 815 {
 816     jthread *pthread;

 817     jclass *pclazz;
 818     jobject *pobject;
 819     jthread thread;

 820     jclass clazz;
 821     jobject object;
 822     char sig;
 823 
 824     JNI_FUNC_PTR(env,ExceptionClear)(env);
 825 
 826     if ( evinfo->thread != NULL ) {
 827         pthread = &(evinfo->thread);
 828         thread = *pthread;
 829         *pthread = NULL;
 830         saveGlobalRef(env, thread, pthread);
 831     }






 832     if ( evinfo->clazz != NULL ) {
 833         pclazz = &(evinfo->clazz);
 834         clazz = *pclazz;
 835         *pclazz = NULL;
 836         saveGlobalRef(env, clazz, pclazz);
 837     }
 838     if ( evinfo->object != NULL ) {
 839         pobject = &(evinfo->object);
 840         object = *pobject;
 841         *pobject = NULL;
 842         saveGlobalRef(env, object, pobject);
 843     }
 844 
 845     switch (evinfo->ei) {
 846         case EI_FIELD_MODIFICATION:
 847             if ( evinfo->u.field_modification.field_clazz != NULL ) {
 848                 pclazz = &(evinfo->u.field_modification.field_clazz);
 849                 clazz = *pclazz;
 850                 *pclazz = NULL;
 851                 saveGlobalRef(env, clazz, pclazz);


 875                 *pclazz = NULL;
 876                 saveGlobalRef(env, clazz, pclazz);
 877             }
 878             break;
 879         default:
 880             break;
 881     }
 882 
 883     if (JNI_FUNC_PTR(env,ExceptionOccurred)(env)) {
 884         EXIT_ERROR(AGENT_ERROR_INVALID_EVENT_TYPE,"ExceptionOccurred");
 885     }
 886 }
 887 
 888 static void
 889 tossEventInfoRefs(JNIEnv *env, EventInfo *evinfo)
 890 {
 891     char sig;
 892     if ( evinfo->thread != NULL ) {
 893         tossGlobalRef(env, &(evinfo->thread));
 894     }



 895     if ( evinfo->clazz != NULL ) {
 896         tossGlobalRef(env, &(evinfo->clazz));
 897     }
 898     if ( evinfo->object != NULL ) {
 899         tossGlobalRef(env, &(evinfo->object));
 900     }
 901     switch (evinfo->ei) {
 902         case EI_FIELD_MODIFICATION:
 903             if ( evinfo->u.field_modification.field_clazz != NULL ) {
 904                 tossGlobalRef(env, &(evinfo->u.field_modification.field_clazz));
 905             }
 906             sig = evinfo->u.field_modification.signature_type;
 907             if ((sig == JDWP_TAG(ARRAY)) || (sig == JDWP_TAG(OBJECT))) {
 908                 if ( evinfo->u.field_modification.new_value.l != NULL ) {
 909                     tossGlobalRef(env, &(evinfo->u.field_modification.new_value.l));
 910                 }
 911             }
 912             break;
 913         case EI_FIELD_ACCESS:
 914             if ( evinfo->u.field_access.field_clazz != NULL ) {


1027     recc = &command->u.reportEventComposite;
1028     recc->suspendPolicy = suspendPolicy;
1029     recc->eventCount = size;
1030     tracker.recc = recc;
1031     tracker.index = 0;
1032     (void)bagEnumerateOver(eventBag, enumForCopyingSingles, &tracker);
1033 
1034     /*
1035      * We must wait if this thread (the event thread) is to be
1036      * suspended or if the VM is about to die. (Waiting in the latter
1037      * case ensures that we get the event out before the process dies.)
1038      */
1039     wait = (jboolean)((suspendPolicy != JDWP_SUSPEND_POLICY(NONE)) ||
1040                       reportingVMDeath);
1041     enqueueCommand(command, wait, reportingVMDeath);
1042     return suspendPolicy;
1043 }
1044 
1045 void
1046 eventHelper_recordEvent(EventInfo *evinfo, jint id, jbyte suspendPolicy,
1047                          struct bag *eventBag)
1048 {
1049     JNIEnv *env = getEnv();
1050     CommandSingle *command = bagAdd(eventBag);
1051     if (command == NULL) {
1052         EXIT_ERROR(AGENT_ERROR_OUT_OF_MEMORY,"badAdd(eventBag)");
1053     }
1054 
1055     command->singleKind = COMMAND_SINGLE_EVENT;
1056     command->u.eventCommand.suspendPolicy = suspendPolicy;
1057     command->u.eventCommand.id = id;
1058 
1059     /*
1060      * Copy the event into the command so that it can be used
1061      * asynchronously by the event helper thread.
1062      */
1063     (void)memcpy(&command->u.eventCommand.info, evinfo, sizeof(*evinfo));
1064     saveEventInfoRefs(env, &command->u.eventCommand.info);
1065 }
1066 
1067 void
1068 eventHelper_recordClassUnload(jint id, char *signature, struct bag *eventBag)
1069 {
1070     CommandSingle *command = bagAdd(eventBag);
1071     if (command == NULL) {
1072         EXIT_ERROR(AGENT_ERROR_OUT_OF_MEMORY,"bagAdd(eventBag)");




 267     return command;
 268 }
 269 
 270 void eventHelper_holdEvents(void)
 271 {
 272     debugMonitorEnter(commandQueueLock);
 273     holdEvents = JNI_TRUE;
 274     debugMonitorNotifyAll(commandQueueLock);
 275     debugMonitorExit(commandQueueLock);
 276 }
 277 
 278 void eventHelper_releaseEvents(void)
 279 {
 280     debugMonitorEnter(commandQueueLock);
 281     holdEvents = JNI_FALSE;
 282     debugMonitorNotifyAll(commandQueueLock);
 283     debugMonitorExit(commandQueueLock);
 284 }
 285 
 286 static void
 287 writeThreadOrFiber(JNIEnv *env, PacketOutputStream *out, EventInfo *evinfo)
 288 {
 289     /*
 290      * Write the fiber ref if the event matched a fiber filter, or if the event was not
 291      * filtered by thread, and came in on a carrier thread running a fiber. In either
 292      * case evinfo->matchesFiber will be true.
 293      */
 294     jthread thread = (evinfo->matchesFiber ? evinfo->fiber : evinfo->thread);
 295     (void)outStream_writeObjectRef(env, out, thread);
 296 }
 297 
 298 static void
 299 writeSingleStepEvent(JNIEnv *env, PacketOutputStream *out, EventInfo *evinfo)
 300 {
 301     writeThreadOrFiber(env, out, evinfo);
 302     writeCodeLocation(out, evinfo->clazz, evinfo->method, evinfo->location);
 303 }
 304 
 305 static void
 306 writeBreakpointEvent(JNIEnv *env, PacketOutputStream *out, EventInfo *evinfo)
 307 {
 308     writeThreadOrFiber(env, out, evinfo);
 309     writeCodeLocation(out, evinfo->clazz, evinfo->method, evinfo->location);
 310 }
 311 
 312 static void
 313 writeFieldAccessEvent(JNIEnv *env, PacketOutputStream *out, EventInfo *evinfo)
 314 {
 315     jbyte fieldClassTag;
 316 
 317     fieldClassTag = referenceTypeTag(evinfo->u.field_access.field_clazz);
 318 
 319     writeThreadOrFiber(env, out, evinfo);
 320     writeCodeLocation(out, evinfo->clazz, evinfo->method, evinfo->location);
 321     (void)outStream_writeByte(out, fieldClassTag);
 322     (void)outStream_writeObjectRef(env, out, evinfo->u.field_access.field_clazz);
 323     (void)outStream_writeFieldID(out, evinfo->u.field_access.field);
 324     (void)outStream_writeObjectTag(env, out, evinfo->object);
 325     (void)outStream_writeObjectRef(env, out, evinfo->object);
 326 }
 327 
 328 static void
 329 writeFieldModificationEvent(JNIEnv *env, PacketOutputStream *out,
 330                             EventInfo *evinfo)
 331 {
 332     jbyte fieldClassTag;
 333 
 334     fieldClassTag = referenceTypeTag(evinfo->u.field_modification.field_clazz);
 335 
 336     writeThreadOrFiber(env, out, evinfo);
 337     writeCodeLocation(out, evinfo->clazz, evinfo->method, evinfo->location);
 338     (void)outStream_writeByte(out, fieldClassTag);
 339     (void)outStream_writeObjectRef(env, out, evinfo->u.field_modification.field_clazz);
 340     (void)outStream_writeFieldID(out, evinfo->u.field_modification.field);
 341     (void)outStream_writeObjectTag(env, out, evinfo->object);
 342     (void)outStream_writeObjectRef(env, out, evinfo->object);
 343     (void)outStream_writeValue(env, out, (jbyte)evinfo->u.field_modification.signature_type,
 344                          evinfo->u.field_modification.new_value);
 345 }
 346 
 347 static void
 348 writeExceptionEvent(JNIEnv *env, PacketOutputStream *out, EventInfo *evinfo)
 349 {
 350     writeThreadOrFiber(env, out, evinfo);
 351     writeCodeLocation(out, evinfo->clazz, evinfo->method, evinfo->location);
 352     (void)outStream_writeObjectTag(env, out, evinfo->object);
 353     (void)outStream_writeObjectRef(env, out, evinfo->object);
 354     writeCodeLocation(out, evinfo->u.exception.catch_clazz,
 355                       evinfo->u.exception.catch_method, evinfo->u.exception.catch_location);
 356 }
 357 
 358 static void
 359 writeThreadEvent(JNIEnv *env, PacketOutputStream *out, EventInfo *evinfo)
 360 {
 361     writeThreadOrFiber(env, out, evinfo);
 362 }
 363 
 364 static void
 365 writeMonitorEvent(JNIEnv *env, PacketOutputStream *out, EventInfo *evinfo)
 366 {
 367     jclass klass;
 368     writeThreadOrFiber(env, out, evinfo);
 369     (void)outStream_writeObjectTag(env, out, evinfo->object);
 370     (void)outStream_writeObjectRef(env, out, evinfo->object);
 371     if (evinfo->ei == EI_MONITOR_WAIT || evinfo->ei == EI_MONITOR_WAITED) {
 372         /* clazz of evinfo was set to class of monitor object for monitor wait event class filtering.
 373          * So get the method class to write location info.
 374          * See cbMonitorWait() and cbMonitorWaited() function in eventHandler.c.
 375          */
 376         klass=getMethodClass(gdata->jvmti, evinfo->method);
 377         writeCodeLocation(out, klass, evinfo->method, evinfo->location);
 378         if (evinfo->ei == EI_MONITOR_WAIT) {
 379             (void)outStream_writeLong(out, evinfo->u.monitor.timeout);
 380         } else  if (evinfo->ei == EI_MONITOR_WAITED) {
 381             (void)outStream_writeBoolean(out, evinfo->u.monitor.timed_out);
 382         }
 383         /* This runs in a command loop and this thread may not return to java.
 384          * So we need to delete the local ref created by jvmti GetMethodDeclaringClass.
 385          */
 386         JNI_FUNC_PTR(env,DeleteLocalRef)(env, klass);
 387     } else {
 388         writeCodeLocation(out, evinfo->clazz, evinfo->method, evinfo->location);
 389     }
 390 }
 391 
 392 static void
 393 writeClassEvent(JNIEnv *env, PacketOutputStream *out, EventInfo *evinfo)
 394 {
 395     jbyte classTag;
 396     jint status;
 397     char *signature = NULL;
 398     jvmtiError error;
 399 
 400     classTag = referenceTypeTag(evinfo->clazz);
 401     error = classSignature(evinfo->clazz, &signature, NULL);
 402     if (error != JVMTI_ERROR_NONE) {
 403         EXIT_ERROR(error,"signature");
 404     }
 405     status = classStatus(evinfo->clazz);
 406 
 407     writeThreadOrFiber(env, out, evinfo);
 408     (void)outStream_writeByte(out, classTag);
 409     (void)outStream_writeObjectRef(env, out, evinfo->clazz);
 410     (void)outStream_writeString(out, signature);
 411     (void)outStream_writeInt(out, map2jdwpClassStatus(status));
 412     jvmtiDeallocate(signature);
 413 }
 414 
 415 static void
 416 writeVMDeathEvent(JNIEnv *env, PacketOutputStream *out, EventInfo *evinfo)
 417 {
 418 }
 419 
 420 static void
 421 handleEventCommandSingle(JNIEnv *env, PacketOutputStream *out,
 422                            EventCommandSingle *command)
 423 {
 424     EventInfo *evinfo = &command->info;
 425 
 426     (void)outStream_writeByte(out, eventIndex2jdwp(evinfo->ei));
 427     (void)outStream_writeInt(out, command->id);


 429     switch (evinfo->ei) {
 430         case EI_SINGLE_STEP:
 431             writeSingleStepEvent(env, out, evinfo);
 432             break;
 433         case EI_BREAKPOINT:
 434             writeBreakpointEvent(env, out, evinfo);
 435             break;
 436         case EI_FIELD_ACCESS:
 437             writeFieldAccessEvent(env, out, evinfo);
 438             break;
 439         case EI_FIELD_MODIFICATION:
 440             writeFieldModificationEvent(env, out, evinfo);
 441             break;
 442         case EI_EXCEPTION:
 443             writeExceptionEvent(env, out, evinfo);
 444             break;
 445         case EI_THREAD_START:
 446         case EI_THREAD_END:
 447             writeThreadEvent(env, out, evinfo);
 448             break;
 449         case EI_FIBER_SCHEDULED:
 450         case EI_FIBER_TERMINATED:
 451             /* Note that when we wrote the evinfo->ei byte above, it was mapped to an EI_THREAD_XXX event
 452              * by eventIndex2jdwp(), so we didn't actually write the FIBER ei byte.
 453              */
 454             writeThreadEvent(env, out, evinfo);
 455             break;
 456         case EI_FIBER_MOUNT:
 457         case EI_FIBER_UNMOUNT:
 458         case EI_CONTINUATION_RUN:
 459         case EI_CONTINUATION_YIELD:
 460             EXIT_ERROR(AGENT_ERROR_INVALID_EVENT_TYPE, "invalid event index");
 461             break;
 462         case EI_CLASS_LOAD:
 463         case EI_CLASS_PREPARE:
 464             writeClassEvent(env, out, evinfo);
 465             break;
 466         case EI_MONITOR_CONTENDED_ENTER:
 467         case EI_MONITOR_CONTENDED_ENTERED:
 468         case EI_MONITOR_WAIT:
 469         case EI_MONITOR_WAITED:
 470             writeMonitorEvent(env, out, evinfo);
 471             break;
 472         case EI_VM_DEATH:
 473             writeVMDeathEvent(env, out, evinfo);
 474             break;
 475         default:
 476             EXIT_ERROR(AGENT_ERROR_INVALID_EVENT_TYPE,"unknown event index");
 477             break;
 478     }
 479     tossEventInfoRefs(env, evinfo);
 480 }
 481 


 822         return;
 823     }
 824     if (commandLoopEnteredVmDeathLock == JNI_TRUE) {
 825         debugMonitorExit(vmDeathLock);
 826         commandLoopEnteredVmDeathLock = JNI_FALSE;
 827     }
 828 }
 829 
 830 void
 831 commandLoop_sync(void)
 832 {
 833     debugMonitorEnter(vmDeathLock);
 834     debugMonitorExit(vmDeathLock);
 835 }
 836 
 837 /* Change all references to global in the EventInfo struct */
 838 static void
 839 saveEventInfoRefs(JNIEnv *env, EventInfo *evinfo)
 840 {
 841     jthread *pthread;
 842     jthread *pfiber;
 843     jclass *pclazz;
 844     jobject *pobject;
 845     jthread thread;
 846     jthread fiber;
 847     jclass clazz;
 848     jobject object;
 849     char sig;
 850 
 851     JNI_FUNC_PTR(env,ExceptionClear)(env);
 852 
 853     if ( evinfo->thread != NULL ) {
 854         pthread = &(evinfo->thread);
 855         thread = *pthread;
 856         *pthread = NULL;
 857         saveGlobalRef(env, thread, pthread);
 858     }
 859     if ( evinfo->fiber != NULL ) {
 860         pfiber = &(evinfo->fiber);
 861         fiber = *pfiber;
 862         *pfiber = NULL;
 863         saveGlobalRef(env, fiber, pfiber);
 864     }
 865     if ( evinfo->clazz != NULL ) {
 866         pclazz = &(evinfo->clazz);
 867         clazz = *pclazz;
 868         *pclazz = NULL;
 869         saveGlobalRef(env, clazz, pclazz);
 870     }
 871     if ( evinfo->object != NULL ) {
 872         pobject = &(evinfo->object);
 873         object = *pobject;
 874         *pobject = NULL;
 875         saveGlobalRef(env, object, pobject);
 876     }
 877 
 878     switch (evinfo->ei) {
 879         case EI_FIELD_MODIFICATION:
 880             if ( evinfo->u.field_modification.field_clazz != NULL ) {
 881                 pclazz = &(evinfo->u.field_modification.field_clazz);
 882                 clazz = *pclazz;
 883                 *pclazz = NULL;
 884                 saveGlobalRef(env, clazz, pclazz);


 908                 *pclazz = NULL;
 909                 saveGlobalRef(env, clazz, pclazz);
 910             }
 911             break;
 912         default:
 913             break;
 914     }
 915 
 916     if (JNI_FUNC_PTR(env,ExceptionOccurred)(env)) {
 917         EXIT_ERROR(AGENT_ERROR_INVALID_EVENT_TYPE,"ExceptionOccurred");
 918     }
 919 }
 920 
 921 static void
 922 tossEventInfoRefs(JNIEnv *env, EventInfo *evinfo)
 923 {
 924     char sig;
 925     if ( evinfo->thread != NULL ) {
 926         tossGlobalRef(env, &(evinfo->thread));
 927     }
 928     if ( evinfo->fiber != NULL ) {
 929         tossGlobalRef(env, &(evinfo->fiber));
 930     }
 931     if ( evinfo->clazz != NULL ) {
 932         tossGlobalRef(env, &(evinfo->clazz));
 933     }
 934     if ( evinfo->object != NULL ) {
 935         tossGlobalRef(env, &(evinfo->object));
 936     }
 937     switch (evinfo->ei) {
 938         case EI_FIELD_MODIFICATION:
 939             if ( evinfo->u.field_modification.field_clazz != NULL ) {
 940                 tossGlobalRef(env, &(evinfo->u.field_modification.field_clazz));
 941             }
 942             sig = evinfo->u.field_modification.signature_type;
 943             if ((sig == JDWP_TAG(ARRAY)) || (sig == JDWP_TAG(OBJECT))) {
 944                 if ( evinfo->u.field_modification.new_value.l != NULL ) {
 945                     tossGlobalRef(env, &(evinfo->u.field_modification.new_value.l));
 946                 }
 947             }
 948             break;
 949         case EI_FIELD_ACCESS:
 950             if ( evinfo->u.field_access.field_clazz != NULL ) {


1063     recc = &command->u.reportEventComposite;
1064     recc->suspendPolicy = suspendPolicy;
1065     recc->eventCount = size;
1066     tracker.recc = recc;
1067     tracker.index = 0;
1068     (void)bagEnumerateOver(eventBag, enumForCopyingSingles, &tracker);
1069 
1070     /*
1071      * We must wait if this thread (the event thread) is to be
1072      * suspended or if the VM is about to die. (Waiting in the latter
1073      * case ensures that we get the event out before the process dies.)
1074      */
1075     wait = (jboolean)((suspendPolicy != JDWP_SUSPEND_POLICY(NONE)) ||
1076                       reportingVMDeath);
1077     enqueueCommand(command, wait, reportingVMDeath);
1078     return suspendPolicy;
1079 }
1080 
1081 void
1082 eventHelper_recordEvent(EventInfo *evinfo, jint id, jbyte suspendPolicy,
1083                         struct bag *eventBag)
1084 {
1085     JNIEnv *env = getEnv();
1086     CommandSingle *command = bagAdd(eventBag);
1087     if (command == NULL) {
1088         EXIT_ERROR(AGENT_ERROR_OUT_OF_MEMORY,"bagAdd(eventBag)");
1089     }
1090 
1091     command->singleKind = COMMAND_SINGLE_EVENT;
1092     command->u.eventCommand.suspendPolicy = suspendPolicy;
1093     command->u.eventCommand.id = id;
1094 
1095     /*
1096      * Copy the event into the command so that it can be used
1097      * asynchronously by the event helper thread.
1098      */
1099     (void)memcpy(&command->u.eventCommand.info, evinfo, sizeof(*evinfo));
1100     saveEventInfoRefs(env, &command->u.eventCommand.info);
1101 }
1102 
1103 void
1104 eventHelper_recordClassUnload(jint id, char *signature, struct bag *eventBag)
1105 {
1106     CommandSingle *command = bagAdd(eventBag);
1107     if (command == NULL) {
1108         EXIT_ERROR(AGENT_ERROR_OUT_OF_MEMORY,"bagAdd(eventBag)");


< prev index next >