in modules/jpda/src/main/native/jdwp/common/agent/core/RequestManager.cpp [2010:2152]
void JNICALL RequestManager::HandleSingleStep(jvmtiEnv* jvmti, JNIEnv* jni,
jthread thread, jmethodID method, jlocation location)
{
JDWP_TRACE_ENTRY("HandleSingleStep(" << jvmti << ',' << jni << ',' << thread
<< ',' << method << ',' << location << ')');
// if is popFrames process, invoke internal handler of step event
if (GetThreadManager().IsPopFramesProcess(jni, thread)) {
GetThreadManager().HandleInternalSingleStep(jni, thread, method, location);
return;
}
// if in agent thread, ignore event
if (GetThreadManager().IsAgentThread(jni, thread)) {
return;
}
try {
jvmtiError err;
EventInfo eInfo;
memset(&eInfo, 0, sizeof(eInfo));
eInfo.kind = JDWP_EVENT_SINGLE_STEP;
eInfo.thread = thread;
eInfo.method = method;
eInfo.location = location;
CombinedEventsInfo::CombinedEventsKind combinedKind = CombinedEventsInfo::COMBINED_EVENT_SINGLE_STEP;
// if this combined event was already prediced, ignore event
if (GetRequestManager().IsPredictedCombinedEvent(jni, eInfo, combinedKind)) {
return;
}
JVMTI_TRACE(err, GetJvmtiEnv()->GetMethodDeclaringClass(method,
&eInfo.cls));
if (err != JVMTI_ERROR_NONE) {
throw AgentException(err);
}
JVMTI_TRACE(err, GetJvmtiEnv()->GetClassSignature(eInfo.cls,
&eInfo.signature, 0));
JvmtiAutoFree jafSignature(eInfo.signature);
if (err != JVMTI_ERROR_NONE) {
throw AgentException(err);
}
#ifndef NDEBUG
if (JDWP_TRACE_ENABLED(LOG_KIND_EVENT)) {
char* name = 0;
JVMTI_TRACE(err, GetJvmtiEnv()->GetMethodName(eInfo.method, &name, 0, 0));
jvmtiThreadInfo info;
JVMTI_TRACE(err, GetJvmtiEnv()->GetThreadInfo(thread, &info));
JDWP_TRACE_EVENT("SINGLE_STEP event:"
<< " class=" << JDWP_CHECK_NULL(eInfo.signature)
<< " method=" << JDWP_CHECK_NULL(name)
<< " loc=" << eInfo.location
<< " thread=" << JDWP_CHECK_NULL(info.name));
}
#endif // NDEBUG
// create new info about combined events for this location
CombinedEventsInfo* combinedEvents = new CombinedEventsInfo();
combinedEvents->Init(jni, eInfo);
// generate SINGLE_STEP events according to existing requests
jdwpSuspendPolicy sp = JDWP_SUSPEND_NONE;
CombinedEventsInfo::CombinedEventsList* events =
&combinedEvents->m_combinedEventsLists[combinedKind];
GetRequestManager().GenerateEvents(jni, eInfo, events->count, events->list, sp);
JDWP_TRACE_EVENT("HandleSingleStep: SINGLE_STEP events:"
<< " count=" << events->count
<< ", suspendPolicy=" << sp
<< ", location=" << combinedEvents->m_eInfo.location);
// if no SINGLE_STEP events then return from callback
if (events->count <= 0) {
combinedEvents->Clean(jni);
delete combinedEvents;
combinedEvents = 0;
return;
}
// check if extra combined events should be generated: BREAKPOINT, METHOD_EXIT
{
// check for BREAKPOINT events
{
combinedKind = CombinedEventsInfo::COMBINED_EVENT_BREAKPOINT;
events = &combinedEvents->m_combinedEventsLists[combinedKind];
eInfo.kind = JDWP_EVENT_BREAKPOINT;
// generate extra events
GetRequestManager().GenerateEvents(jni, eInfo, events->count, events->list, sp);
JDWP_TRACE_EVENT("HandleSingleStep: BREAKPOINT events:"
<< " count=" << events->count
<< ", suspendPolicy=" << sp
<< ", location=" << combinedEvents->m_eInfo.location);
// check if corresponding callback should be ignored
if (events->count > 0) {
events->ignored = 1;
}
}
// check for METHOD_EXIT events
if (ENABLE_COMBINED_METHOD_EXIT_EVENT) {
if (GetRequestManager().IsMethodExitLocation(jni, eInfo)) {
combinedKind = CombinedEventsInfo::COMBINED_EVENT_METHOD_EXIT;
events = &combinedEvents->m_combinedEventsLists[combinedKind];
eInfo.kind = JDWP_EVENT_METHOD_EXIT;
// generate extra events
GetRequestManager().GenerateEvents(jni, eInfo, events->count, events->list, sp);
JDWP_TRACE_EVENT("HandleSingleStep: METHOD_EXIT events:"
<< " count=" << events->count
<< ", suspendPolicy=" << sp
<< ", location=" << combinedEvents->m_eInfo.location);
// check if corresponding callback should be ignored
if (events->count > 0) {
events->ignored = 1;
}
}
}
}
// post all generated events
EventComposer *ec = GetRequestManager().CombineEvents(jni, combinedEvents, sp);
JDWP_TRACE_EVENT("HandleSingleStep: post set of " << combinedEvents->GetEventsCount() << " events");
GetEventDispatcher().PostEventSet(jni, ec, JDWP_EVENT_SINGLE_STEP);
// store info about combined events if other callbacks should be ignored
if (combinedEvents->GetIgnoredCallbacksCount() > 0) {
JDWP_TRACE_EVENT("HandleSingleStep: store combined events for new location:"
<< " method=" << eInfo.method
<< " loc=" << eInfo.location);
GetRequestManager().AddCombinedEventsInfo(jni, combinedEvents);
} else {
combinedEvents->Clean(jni);
delete combinedEvents;
combinedEvents = 0;
}
} catch (AgentException& e) {
JDWP_INFO("JDWP error in SINGLE_STEP: " << e.what() << " [" << e.ErrCode() << "]");
}
}