void transport_initialize(void) { transport = NULL; listenerLock = debugMonitorCreate("JDWP Transport Listener Monitor"); sendLock = debugMonitorCreate("JDWP Transport Send Monitor"); }
/* Initialize the commonRefs usage */ void commonRef_initialize(void) { gdata->refLock = debugMonitorCreate("JDWP Reference Table Monitor"); gdata->nextSeqNum = 1; /* 0 used for error indication */ initializeObjectsByID(HASH_INIT_SIZE); }
void eventHelper_initialize(jbyte sessionID) { jvmtiStartFunction func; currentSessionID = sessionID; holdEvents = JNI_FALSE; commandQueue.head = NULL; commandQueue.tail = NULL; commandQueueLock = debugMonitorCreate("JDWP Event Helper Queue Monitor"); commandCompleteLock = debugMonitorCreate("JDWP Event Helper Completion Monitor"); blockCommandLoopLock = debugMonitorCreate("JDWP Event Block CommandLoop Monitor"); /* Start the event handler thread */ func = &commandLoop; (void)spawnNewThread(func, NULL, "JDWP Event Helper Thread"); }
void commonRef_initialize(void) { refLock = debugMonitorCreate("JDWP Reference Table Monitor"); nextSeqNum = 1; /* 0 used for error indication */ }
/* * Initialize debugger back end modules */ static void initialize(JNIEnv *env, jthread thread, EventIndex triggering_ei) { jvmtiError error; EnumerateArg arg; jbyte suspendPolicy; LOG_MISC(("Begin initialize()")); currentSessionID = 0; initComplete = JNI_FALSE; if ( gdata->vmDead ) { EXIT_ERROR(AGENT_ERROR_INTERNAL,"VM dead at initialize() time"); } /* Turn off the initial JVMTI event notifications */ error = set_event_notification(JVMTI_DISABLE, EI_EXCEPTION); if (error != JVMTI_ERROR_NONE) { EXIT_ERROR(error, "unable to disable JVMTI event notification"); } error = set_event_notification(JVMTI_DISABLE, EI_VM_INIT); if (error != JVMTI_ERROR_NONE) { EXIT_ERROR(error, "unable to disable JVMTI event notification"); } error = set_event_notification(JVMTI_DISABLE, EI_VM_DEATH); if (error != JVMTI_ERROR_NONE) { EXIT_ERROR(error, "unable to disable JVMTI event notification"); } /* Remove initial event callbacks */ (void)memset(&(gdata->callbacks),0,sizeof(gdata->callbacks)); error = JVMTI_FUNC_PTR(gdata->jvmti,SetEventCallbacks) (gdata->jvmti, &(gdata->callbacks), sizeof(gdata->callbacks)); if (error != JVMTI_ERROR_NONE) { EXIT_ERROR(error, "unable to clear JVMTI callbacks"); } commonRef_initialize(); util_initialize(env); threadControl_initialize(); stepControl_initialize(); invoker_initialize(); debugDispatch_initialize(); classTrack_initialize(env); debugLoop_initialize(); initMonitor = debugMonitorCreate("JDWP Initialization Monitor"); /* * Initialize transports */ arg.isServer = isServer; arg.error = JDWP_ERROR(NONE); arg.startCount = 0; transport_initialize(); (void)bagEnumerateOver(transports, startTransport, &arg); /* * Exit with an error only if * 1) none of the transports was successfully started, and * 2) the application has not yet started running */ if ((arg.error != JDWP_ERROR(NONE)) && (arg.startCount == 0) && initOnStartup) { EXIT_ERROR(map2jvmtiError(arg.error), "No transports initialized"); } eventHandler_initialize(currentSessionID); signalInitComplete(); transport_waitForConnection(); suspendPolicy = suspendOnInit ? JDWP_SUSPEND_POLICY(ALL) : JDWP_SUSPEND_POLICY(NONE); if (triggering_ei == EI_VM_INIT) { LOG_MISC(("triggering_ei == EI_VM_INIT")); eventHelper_reportVMInit(env, currentSessionID, thread, suspendPolicy); } else { /* * TO DO: Kludgy way of getting the triggering event to the * just-attached debugger. It would be nice to make this a little * cleaner. There is also a race condition where other events * can get in the queue (from other not-yet-suspended threads) * before this one does. (Also need to handle allocation error below?) */ EventInfo info; struct bag *initEventBag; LOG_MISC(("triggering_ei != EI_VM_INIT")); initEventBag = eventHelper_createEventBag(); (void)memset(&info,0,sizeof(info)); info.ei = triggering_ei; eventHelper_recordEvent(&info, 0, suspendPolicy, initEventBag); (void)eventHelper_reportEvents(currentSessionID, initEventBag); bagDestroyBag(initEventBag); } if ( gdata->vmDead ) { EXIT_ERROR(AGENT_ERROR_INTERNAL,"VM dead before initialize() completes"); } LOG_MISC(("End initialize()")); }
void debugLoop_run(void) { jboolean shouldListen; jdwpPacket p; jvmtiStartFunction func; /* Initialize all statics */ /* We may be starting a new connection after an error */ cmdQueue = NULL; cmdQueueLock = debugMonitorCreate("JDWP Command Queue Lock"); transportError = JNI_FALSE; shouldListen = JNI_TRUE; func = &reader; (void)spawnNewThread(func, NULL, "JDWP Command Reader"); standardHandlers_onConnect(); threadControl_onConnect(); /* Okay, start reading cmds! */ while (shouldListen) { if (!dequeue(&p)) { break; } if (p.type.cmd.flags & JDWPTRANSPORT_FLAGS_REPLY) { /* * Its a reply packet. */ continue; } else { /* * Its a cmd packet. */ jdwpCmdPacket *cmd = &p.type.cmd; PacketInputStream in; PacketOutputStream out; CommandHandler func; /* Should reply be sent to sender. * For error handling, assume yes, since * only VM/exit does not reply */ jboolean replyToSender = JNI_TRUE; /* * For VirtualMachine.Resume commands we hold the resumeLock * while executing and replying to the command. This ensures * that a Resume after VM_DEATH will be allowed to complete * before the thread posting the VM_DEATH continues VM * termination. */ if (resumeCommand(cmd)) { debugMonitorEnter(resumeLock); } /* Initialize the input and output streams */ inStream_init(&in, p); outStream_initReply(&out, inStream_id(&in)); LOG_MISC(("Command set %d, command %d", cmd->cmdSet, cmd->cmd)); func = debugDispatch_getHandler(cmd->cmdSet,cmd->cmd); if (func == NULL) { /* we've never heard of this, so I guess we * haven't implemented it. * Handle gracefully for future expansion * and platform / vendor expansion. */ outStream_setError(&out, JDWP_ERROR(NOT_IMPLEMENTED)); } else if (gdata->vmDead && ((cmd->cmdSet) != JDWP_COMMAND_SET(VirtualMachine))) { /* Protect the VM from calls while dead. * VirtualMachine cmdSet quietly ignores some cmds * after VM death, so, it sends it's own errors. */ outStream_setError(&out, JDWP_ERROR(VM_DEAD)); } else { /* Call the command handler */ replyToSender = func(&in, &out); } /* Reply to the sender */ if (replyToSender) { if (inStream_error(&in)) { outStream_setError(&out, inStream_error(&in)); } outStream_sendReply(&out); } /* * Release the resumeLock as the reply has been posted. */ if (resumeCommand(cmd)) { debugMonitorExit(resumeLock); } inStream_destroy(&in); outStream_destroy(&out); shouldListen = !lastCommand(cmd); } } threadControl_onDisconnect(); standardHandlers_onDisconnect(); /* * Cut off the transport immediately. This has the effect of * cutting off any events that the eventHelper thread might * be trying to send. */ transport_close(); debugMonitorDestroy(cmdQueueLock); /* Reset for a new connection to this VM if it's still alive */ if ( ! gdata->vmDead ) { debugInit_reset(getEnv()); } }
void debugLoop_initialize(void) { resumeLock = debugMonitorCreate("JDWP Resume Lock"); }