in modules/jpda/src/main/native/jdwp/common/agent/core/RequestManager.cpp [256:361]
void RequestManager::ControlEvent(JNIEnv* jni,
AgentEventRequest* request, bool enable)
throw(AgentException)
{
JDWP_TRACE_ENTRY("ControlEvent(" << jni << ',' << request << ',' << enable << ")");
jvmtiEvent eventType;
bool nullThreadForSetEventNotificationMode = false;
switch (request->GetEventKind()) {
case JDWP_EVENT_SINGLE_STEP:
// manually controlled inside StepRequest
//eventType = JVMTI_EVENT_SINGLE_STEP;
//break;
return;
case JDWP_EVENT_BREAKPOINT:
eventType = JVMTI_EVENT_BREAKPOINT;
ControlBreakpoint(jni, request, enable);
break;
case JDWP_EVENT_FRAME_POP:
eventType = JVMTI_EVENT_FRAME_POP;
break;
case JDWP_EVENT_EXCEPTION:
eventType = JVMTI_EVENT_EXCEPTION;
break;
case JDWP_EVENT_CLASS_PREPARE:
eventType = JVMTI_EVENT_CLASS_PREPARE;
break;
case JDWP_EVENT_CLASS_LOAD:
eventType = JVMTI_EVENT_CLASS_LOAD;
break;
case JDWP_EVENT_CLASS_UNLOAD:
eventType = static_cast<jvmtiEvent>(
ControlClassUnload(jni, request, enable));
// avoid standard event enable/disable technique
return;
case JDWP_EVENT_FIELD_ACCESS:
eventType = JVMTI_EVENT_FIELD_ACCESS;
ControlWatchpoint(jni, request, enable);
break;
case JDWP_EVENT_FIELD_MODIFICATION:
eventType = JVMTI_EVENT_FIELD_MODIFICATION;
ControlWatchpoint(jni, request, enable);
break;
case JDWP_EVENT_EXCEPTION_CATCH:
eventType = JVMTI_EVENT_EXCEPTION_CATCH;
break;
case JDWP_EVENT_METHOD_ENTRY:
eventType = JVMTI_EVENT_METHOD_ENTRY;
break;
case JDWP_EVENT_METHOD_EXIT:
eventType = JVMTI_EVENT_METHOD_EXIT;
break;
case JDWP_EVENT_THREAD_START:
eventType = JVMTI_EVENT_THREAD_START;
nullThreadForSetEventNotificationMode = true;
break;
case JDWP_EVENT_THREAD_END:
eventType = JVMTI_EVENT_THREAD_END;
nullThreadForSetEventNotificationMode = true;
break;
default:
return;
}
jthread thread = request->GetThread();
RequestList& rl = GetRequestList(request->GetEventKind());
for (RequestListIterator i = rl.begin(); i != rl.end(); i++) {
if (nullThreadForSetEventNotificationMode) {
//
// SetEventNotificationMode() for some events must be called with
// jthread = 0, even if we need request only for specified thread.
// Thus, if there is already any request for such events
// it is for all threads and SetEventNotificationMode() should not
// be called.
//
return;
}
AgentEventRequest* req = *i;
if (JNI_TRUE == jni->IsSameObject(thread, req->GetThread())) {
// there is similar request, so do nothing
return;
}
}
JDWP_TRACE_EVENT("ControlEvent: request " << GetEventKindName(request->GetEventKind())
<< "[" << request->GetEventKind() << "] "
<< (enable ? "on" : "off") << ", thread=" << thread);
jvmtiError err;
if (nullThreadForSetEventNotificationMode) {
//
// SetEventNotificationMode() for some events must be called with
// jthread = 0, even if we need request only for specified thread.
// Thus, if request is for such event, SetEventNotificationMode()
// should be called with jthread = 0 and generated events will be
// filtered later
//
thread = 0;
}
JVMTI_TRACE(err, GetJvmtiEnv()->SetEventNotificationMode(
(enable) ? JVMTI_ENABLE : JVMTI_DISABLE, eventType, thread));
if (err != JVMTI_ERROR_NONE &&
(err != JVMTI_ERROR_THREAD_NOT_ALIVE || enable))
{
throw AgentException(err);
}
}