📄 debugger.c
字号:
/*======================================================================== * Function: setEvent_NeedSteppingInfo() * Overview: tell the _proxy_ that _we_ need info about class lines * * Interface: * parameters: pointer to thread that's stepping * pointer to CEMod structure * returns: void * * Notes: Since this is called re-entrantly via createevent, we need * to use our own output packet since on return to createevent * and thence to processCommands, we don't want to have blown the * global outputStream used for most commands *=======================================================================*/static void setEvent_NeedSteppingInfo(unsigned long threadID, CEModPtr cep){ FRAME frame; unsigned long offset; unsigned long methodIndex; METHOD thisMethod; START_TEMPORARY_ROOTS DECLARE_TEMPORARY_ROOT(THREAD, thread, GET_VMTHREAD(threadID)); DECLARE_TEMPORARY_ROOT(PACKET_INPUT_STREAM, out, outStream_newCommand(FLAGS_None, KVM_CMDSET, KVM_STEPPING_EVENT_COMMAND)); DEBUGGER_EVENT(("Need Stepping Info")); if (thread == CurrentThread) { frame = fp_global; offset = ip_global - frame->thisMethod->u.java.code; } else { frame = thread->fpStore; offset = thread->ipStore - frame->thisMethod->u.java.code; } /* Note that frame is volatile, and can be bashed by a GC */ thisMethod = frame->thisMethod; methodIndex = getMethodIndex(thisMethod); outStream_writeLong(&out, (long)cep); outStream_writeClass(&out, (CLASS)(thisMethod->ofClass)); outStream_writeLong(&out, methodIndex); outStream_writeLong64(&out, offset); outStream_sendCommand(&out); END_TEMPORARY_ROOTS}/*======================================================================== * Function: setEvent_VMInit() * Overview: called when the vm starts * * Interface: * parameters: none * returns: void * * Notes: *=======================================================================*/void setEvent_VMInit(){ VMEventPtr reqID; reqID = NIL; START_TEMPORARY_ROOTS DECLARE_TEMPORARY_ROOT(PACKET_OUTPUT_STREAM, out, outStream_newCommand(FLAGS_None, JDWP_COMMAND_SET(Event), JDWP_COMMAND(Event, Composite))); DEBUGGER_EVENT(("VM Init")); if (suspend) { /* Suspend all threads by default */ DEBUGGER_EVENT(("VM Suspend All")); outStream_writeByte(&out, JDWP_SuspendPolicy_ALL); } else { /* Suspend no threads */ DEBUGGER_EVENT(("VM Suspend None")); outStream_writeByte(&out, JDWP_SuspendPolicy_NONE); } outStream_writeLong(&out, 1); outStream_writeByte(&out, JDWP_EventKind_VM_START); outStream_writeLong(&out, (long)reqID); /* hopefully this will be called when CurrentThread==initial_thread */ outStream_writeThread(&out, CurrentThread); outStream_sendCommand(&out); if (suspend) { /* Use suspend policy which suspends all threads by default */ handleSuspendPolicy(JDWP_SuspendPolicy_ALL, CurrentThread, TRUE); } else { /* Use suspend policy which suspends no threads */ DEBUGGER_EVENT(("VM SuspendPolicy not specified")); /* handleSuspendPolicy(JDWP_SuspendPolicy_NONE, CurrentThread, TRUE); */ } END_TEMPORARY_ROOTS}/*======================================================================== * Function: setEvent_VMDeath() * Overview: called when the vm terminates * * Interface: * parameters: none * returns: void * * Notes: *=======================================================================*/void setEvent_VMDeath(){ checkNOTIFY_WANTED(Dbg_EventKind_VM_DEATH); START_TEMPORARY_ROOTS DECLARE_TEMPORARY_ROOT(PACKET_OUTPUT_STREAM, out, outStream_newCommand(FLAGS_None, JDWP_COMMAND_SET(Event), JDWP_COMMAND(Event, Composite))); DEBUGGER_EVENT(("VM Death")); outStream_writeByte(&out, JDWP_SuspendPolicy_ALL); outStream_writeLong(&out, 1); outStream_writeByte(&out, JDWP_EventKind_VM_DEATH); outStream_writeLong(&out, 0); /* spec says always zero */ outStream_sendCommand(&out); END_TEMPORARY_ROOTS}/*======================================================================== * Function: setEvent_MidletDeath() * Overview: called when a midlet is dying * * Interface: * parameters: midlet class * returns: void * * Notes: *=======================================================================*/void setEvent_MidletDeath(CEModPtr cep){ CLASS clazz = GET_DEBUGGERID_CLASS(cep->loc.classID); VMEventPtr ep, epFirst; int eventCount = 0; BYTE suspendPolicy = JDWP_SuspendPolicy_NONE; checkNOTIFY_WANTED(Dbg_EventKind_MIDLET_DEATH); if (!IS_ARRAY_CLASS(clazz) && ((INSTANCE_CLASS)clazz)->status < CLASS_LOADED) { return; } /* In case of an allocation in outStream_writeBytes */ if (findSatisfyingEvent(JDWP_EventKind_MIDLET_DEATH, cep, &epFirst, &eventCount, &suspendPolicy)) { START_TEMPORARY_ROOTS DECLARE_TEMPORARY_ROOT(PACKET_OUTPUT_STREAM, out, outStream_newCommand(FLAGS_None, JDWP_COMMAND_SET(Event), JDWP_COMMAND(Event, Composite))); DEBUGGER_EVENT(("Midlet Death %s", getClassName(clazz))); ep = epFirst; outStream_writeByte(&out, suspendPolicy); outStream_writeLong(&out, eventCount); while (ep != NULL) { outStream_writeByte(&out, JDWP_EventKind_MIDLET_DEATH); outStream_writeLong(&out, (long)ep); outStream_writeClassName(&out, clazz); checkEventCount(ep); ep = ep->sendNext; } outStream_sendCommand(&out); handleSuspendPolicy(suspendPolicy, GET_VMTHREAD(cep->threadID), FALSE); END_TEMPORARY_ROOTS }}/*======================================================================== * Function: setEvent_SingleStep * Overview: * * Interface: * parameters: none * returns: void * * Notes: *=======================================================================*/void setEvent_SingleStep(CEModPtr cep, THREAD threadArg){ VMEventPtr ep, epFirst; int eventCount = 0; BYTE suspendPolicy = JDWP_SuspendPolicy_NONE; checkNOTIFY_WANTED(Dbg_EventKind_SINGLE_STEP); /* In case of an allocation in outStream_writeBytes */ if (findSatisfyingEvent(JDWP_EventKind_SINGLE_STEP, cep, &epFirst, &eventCount, &suspendPolicy)) { ep = epFirst; START_TEMPORARY_ROOTS DECLARE_TEMPORARY_ROOT(PACKET_OUTPUT_STREAM, out, outStream_newCommand(FLAGS_None, JDWP_COMMAND_SET(Event), JDWP_COMMAND(Event, Composite))); DECLARE_TEMPORARY_ROOT(THREAD, thread, threadArg); DEBUGGER_EVENT(("Single Step")); outStream_writeByte(&out, suspendPolicy); outStream_writeLong(&out, eventCount); while (ep != NULL) { outStream_writeByte(&out, JDWP_EventKind_SINGLE_STEP); outStream_writeObjectID(&out, (long)ep); outStream_writeThread(&out, thread); outStream_writeLocation(&out, JDWP_TypeTag_CLASS, cep->loc.classID, cep->loc.methodIndex, cep->loc.offset); checkEventCount(ep); ep = ep->sendNext; } outStream_sendCommand(&out); handleSuspendPolicy(suspendPolicy, thread, FALSE); END_TEMPORARY_ROOTS }}/*======================================================================== * Function: setEvent_Breakpoint() * Overview: sends a break event to debugger * Interface: * parameters: pointer to breakpoint structure, type of event * returns: nothing * * Notes: writes out a composite event packet per JDWP spec *=======================================================================*/void setEvent_Breakpoint(VMEventPtr ep, CEModPtr cep){ EVENTMODIFIER em; /* BYTE suspendPolicy = JDWP_SuspendPolicy_ALL; */ if (!NOTIFY_WANTED(Dbg_EventKind_SINGLE_STEP) && !NOTIFY_WANTED(Dbg_EventKind_BREAKPOINT)) return; em = ep->mods; if (!satisfiesModifiers(ep, cep, em)) { return; } START_TEMPORARY_ROOTS DECLARE_TEMPORARY_ROOT(PACKET_OUTPUT_STREAM, out, outStream_newCommand(FLAGS_None, JDWP_COMMAND_SET(Event), JDWP_COMMAND(Event, Composite))); DEBUGGER_EVENT(("Breakpoint at method: 0x%lx, classID: 0x%lx, offset: 0x%lx", cep->loc.methodIndex, cep->loc.classID, (int)cep->loc.offset)); outStream_writeByte(&out, ep->suspendPolicy); /* count is 1 for now */ outStream_writeLong(&out, 1); outStream_writeByte(&out, JDWP_EventKind_BREAKPOINT); outStream_writeLong(&out, (long)ep); outStream_writeThread(&out, CurrentThread); /* write the Location */ outStream_writeLocation(&out, JDWP_TypeTag_CLASS, cep->loc.classID, cep->loc.methodIndex, cep->loc.offset); outStream_sendCommand(&out); handleSuspendPolicy(ep->suspendPolicy, CurrentThread, FALSE); END_TEMPORARY_ROOTS}/*======================================================================== * Function: setEvent_MethodEntry() * Overview: called when the code enters a method * * Interface: * parameters: none * returns: void * * Notes: *=======================================================================*/void setEvent_MethodEntry(){ checkNOTIFY_WANTED(Dbg_EventKind_METHOD_ENTRY);}/*======================================================================== * Function: setEvent_MethodExit() * Overview: called when the code exits a method * * Interface: * parameters: * returns: * * Notes: *=======================================================================*/void setEvent_MethodExit(){ checkNOTIFY_WANTED(Dbg_EventKind_METHOD_EXIT);}/*======================================================================== * Function: setEvent_ThreadStart() * Overview: called when a thread is created * * Interface: * parameters: none * returns: void * * Notes: *=======================================================================*/void setEvent_ThreadStart(CEModPtr cep){ VMEventPtr ep, epFirst; int eventCount = 0; BYTE suspendPolicy = JDWP_SuspendPolicy_NONE; checkNOTIFY_WANTED(Dbg_EventKind_THREAD_START); if (findSatisfyingEvent(JDWP_EventKind_THREAD_START, cep, &epFirst, &eventCount, &suspendPolicy)) { ep = epFirst; START_TEMPORARY_ROOTS DECLARE_TEMPORARY_ROOT(PACKET_OUTPUT_STREAM, out, outStream_newCommand(FLAGS_None, JDWP_COMMAND_SET(Event), JDWP_COMMAND(Event, Composite))); DEBUGGER_EVENT(("Thread Start ID=%lx", cep->threadID)); outStream_writeByte(&out, suspendPolicy); outStream_writeLong(&out, eventCount); while(ep != NULL) { outStream_writeByte(&out, JDWP_EventKind_THREAD_START); outStream_writeLong(&out, (long)ep); outStream_writeObjectID(&out, cep->threadID); checkEventCount(ep); ep = ep->sendNext; } outStream_sendCommand(&out); handleSuspendPolicy(suspendPolicy, GET_VMTHREAD(cep->threadID), FALSE); END_TEMPORARY_ROOTS }}/*======================================================================== * Function: setEvent_ThreadDeath() * Overview: called when a thread terminates * * Interface: * parameters: * returns: * * Notes: *=======================================================================*/void setEvent_ThreadDeath(CEModPtr cep){ VMEventPtr ep, epFirst; int eventCount = 0; BYTE suspendPolicy = JDWP_SuspendPolicy_NONE; checkNOTIFY_WANTED(Dbg_EventKind_THREAD_END); if (findSatisfyingEvent(JDWP_EventKind_THREAD_END, cep, &epFirst, &eventCount, &suspendPolicy)) { ep = epFirst; START_TEMPORARY_ROOTS DECLARE_TEMPORARY_ROOT(PACKET_OUTPUT_STREAM, out, outStream_newCommand(FLAGS_None, JDWP_COMMAND_SET(Event), JDWP_COMMAND(Event, Composite))); DEBUGGER_EVENT(("Thread Death ID=%lx", cep->threadID)); outStream_writeByte(&out, suspendPolicy); outStream_writeLong(&out, eventCount); while (ep != NULL) { outStream_writeByte(&out, JDWP_EventKind_THREAD_END); outStream_writeLong(&out, (long)ep); outStream_writeObjectID(&out, cep->threadID); checkEventCount(ep); ep = ep->sendNext; } outStream_sendCommand(&out); handleSuspendPolicy(suspendPolicy, GET_VMTHREAD(cep->threadID), FALSE); END_TEMPORARY_ROOTS }}/*======================================================================== * Function: getJDWPClassStatus() * Overview: translates an internal class status * into the JDWP equivalent. * * Interface: * parameters: class pointer * returns: JDWP class status
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -