📄 debugger.c
字号:
* * Notes: *=======================================================================*/int getJDWPClassStatus(INSTANCE_CLASS clazz){ int ret = 0; if (IS_ARRAY_CLASS(clazz)) { return JDWP_ClassStatus_INITIALIZED; } switch (clazz->status) { case CLASS_ERROR: return JDWP_ClassStatus_ERROR; /* case CLASS_RAW: */ case CLASS_READY: ret = JDWP_ClassStatus_INITIALIZED; /* fall through */ case CLASS_LOADING: case CLASS_LOADED: case CLASS_LINKED: ret |= JDWP_ClassStatus_PREPARED; /* fall through */ case CLASS_VERIFIED: ret |= JDWP_ClassStatus_VERIFIED; break; } return ret;}/*======================================================================== * Function: getJDWPThreadStatus() * Overview: translates an internal thread status * into the JDWP equivalent * * Interface: * parameters: thread pointer * returns: JDWP thread status * * Notes: *=======================================================================*/static int getJDWPThreadStatus(THREAD thread){ int state = thread->state; if (state == THREAD_SUSPENDED) { return JDWP_ThreadStatus_RUNNING; } else { state &= ~THREAD_SUSPENDED; state &= ~THREAD_DBG_SUSPENDED; switch (state) { case THREAD_ACTIVE: return JDWP_ThreadStatus_RUNNING; case THREAD_MONITOR_WAIT: return JDWP_ThreadStatus_MONITOR; case THREAD_CONVAR_WAIT: return JDWP_ThreadStatus_WAIT; case THREAD_DEAD: return JDWP_ThreadStatus_ZOMBIE; default: return JDWP_ThreadStatus_UNKNOWN; } }}/*======================================================================== * Function: getJDWPThreadSuspendStatus() * Overview: returns if this thread has been suspended * through the debugger * * Interface: * parameters: thread pointer * returns: suspend status * * Notes: *=======================================================================*/static int getJDWPThreadSuspendStatus(THREAD thread) { int ret = 0; int state = thread->state; if (state == THREAD_SUSPENDED) { ret |= JDWP_SuspendStatus_SUSPEND_STATUS_SUSPENDED; } if (state & THREAD_DBG_SUSPENDED) { ret |= JDWP_SuspendStatus_SUSPEND_STATUS_SUSPENDED; } if ((state & THREAD_MONITOR_WAIT) || (state & THREAD_CONVAR_WAIT)) { ret |= JDWP_SuspendStatus_SUSPEND_STATUS_SUSPENDED; } return ret;}/*======================================================================== * Function: getJDWPTagType() * Overview: determines what kind of class a class is * (array, interface, class) * * Interface: * parameters: class pointer * returns: tag type * * Notes: *=======================================================================*/static BYTE getJDWPTagType(CLASS clazz) { if (IS_ARRAY_CLASS(clazz)) { return JDWP_TypeTag_ARRAY; } else if (clazz->accessFlags & ACC_INTERFACE) { return JDWP_TypeTag_INTERFACE; } else { /* is a class */ return JDWP_TypeTag_CLASS; }}void sendAllClassPrepares() { CEModPtr cep;#if INCLUDEDEBUGCODE int old_tracedebugger = tracedebugger; tracedebugger = 0; if (old_tracedebugger) { DEBUGGER_EVENT(("Class Prepare ... All Classes")); } #endif if (NOTIFY_WANTED(Dbg_EventKind_CLASS_PREPARE)) { cep = GetCEModifier(); FOR_ALL_CLASSES(clazz) cep->loc.classID = GET_CLASS_DEBUGGERID(clazz); cep->threadID = CurrentThread == NULL ? 0 : getObjectID((OBJECT)CurrentThread->javaThread); setEvent_ClassPrepare(cep); END_FOR_ALL_CLASSES FreeCEModifier(cep); }#if INCLUDEDEBUGCODE tracedebugger = old_tracedebugger;#endif}/*======================================================================== * Function: setEvent_ClassPrepare() * Overview: called when a class is loading * * Interface: * parameters: thread pointer, class pointer * returns: void * * Notes: *=======================================================================*/void setEvent_ClassPrepare(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_CLASS_PREPARE); if (!IS_ARRAY_CLASS(clazz) && ((INSTANCE_CLASS)clazz)->status < CLASS_LOADED) { return; } /* In case of an allocation in outStream_writeBytes */ if (findSatisfyingEvent(JDWP_EventKind_CLASS_PREPARE, 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(("Class Prepare %s", getClassName(clazz))); ep = epFirst; outStream_writeByte(&out, suspendPolicy); outStream_writeLong(&out, eventCount); while (ep != NULL) { outStream_writeByte(&out, JDWP_EventKind_CLASS_PREPARE); outStream_writeLong(&out, (long)ep); outStream_writeObjectID(&out, cep->threadID); outStream_writeByte(&out, getJDWPTagType(clazz)); outStream_writeClass(&out, clazz); outStream_writeClassName(&out, clazz); outStream_writeLong(&out, getJDWPClassStatus((INSTANCE_CLASS)clazz)); checkEventCount(ep); ep = ep->sendNext; } outStream_sendCommand(&out); handleSuspendPolicy(suspendPolicy, GET_VMTHREAD(cep->threadID), FALSE); END_TEMPORARY_ROOTS }}/*======================================================================== * Function: setEvent_ClassLoad() * Overview: called when a class is loaded * * Interface: * parameters: thread pointer, class pointer * returns: void * * Notes: *=======================================================================*/void setEvent_ClassLoad(CEModPtr cep){ checkNOTIFY_WANTED(Dbg_EventKind_CLASS_LOAD); setEvent_ClassPrepare(cep);}/*======================================================================== * Function: setEvent_ClassUnload() * Overview: called when a class is unloaded * * Interface: * parameters: thread pointer, class pointer * returns: void * * Notes: *=======================================================================*/void setEvent_ClassUnload(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_CLASS_UNLOAD); /* In case of an allocation in outStream_writeBytes */ if (findSatisfyingEvent(JDWP_EventKind_CLASS_UNLOAD, 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(("Class Unload %s", getClassName(clazz))); ep = epFirst; outStream_writeByte(&out, suspendPolicy); outStream_writeLong(&out, eventCount); while (ep != NULL) { outStream_writeByte(&out, JDWP_EventKind_CLASS_UNLOAD); 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_FieldAccess() * Overview: called when a field is accessed (read) * * Interface: * parameters: none * returns: void * * Notes: *=======================================================================*/void setEvent_FieldAccess(){ checkNOTIFY_WANTED(Dbg_EventKind_FIELD_ACCESS);}/*======================================================================== * Function: setEvent_FieldModification() * Overview: called when a field is modified * * Interface: * parameters: * returns: * * Notes: *=======================================================================*/void setEvent_FieldModification(){ checkNOTIFY_WANTED(Dbg_EventKind_FIELD_MODIFICATION);}/*======================================================================== * Function: setEvent_FramePop() * Overview: * * Interface: * parameters: * returns: * * Notes: *=======================================================================*/void setEvent_FramePop(){ checkNOTIFY_WANTED(Dbg_EventKind_FRAME_POP);}/*======================================================================== * Function: setEvent_Exception() * Overview: * * Interface: * parameters: * returns: * * Notes: *=======================================================================*/void setEvent_Exception(THROWABLE_INSTANCE_HANDLE exceptionH, FRAME throwFrame, BYTE *throwIP, METHOD catchMethod, unsigned long catchOffs, CEModPtr cep){ VMEventPtr ep, epFirst; unsigned long throwOffset; THREAD thread = GET_VMTHREAD(cep->threadID); int eventCount = 0; BYTE suspendPolicy = JDWP_SuspendPolicy_NONE; METHOD thisMethod = throwFrame->thisMethod; checkNOTIFY_WANTED(Dbg_EventKind_EXCEPTION); if (thread->javaThread == NIL) { /* this isn't a java exception */ return; } if (findSatisfyingEvent(JDWP_EventKind_EXCEPTION, cep, &epFirst, &eventCount, &suspendPolicy)) { /* throwFrame is bashed if GC happens */ throwOffset = throwIP - thisMethod->u.java.code; START_TEMPORARY_ROOTS DECLARE_TEMPORARY_ROOT(PACKET_OUTPUT_STREAM, out, outStream_newCommand(FLAGS_None, JDWP_COMMAND_SET(Event), JDWP_COMMAND(Event, Composite))); /* Frame's are in the middle of a stack, and it is hard to make * them into a root */ DEBUGGER_EVENT(("Exception")); ep = epFirst; outStream_writeByte(&out, suspendPolicy); outStream_writeLong(&out, eventCount); while (ep != NULL) { outStream_writeByte(&out, JDWP_EventKind_EXCEPTION); outStream_writeLong(&out, (long)ep); /* thread with exception */ outStream_writeObjectID(&out, cep->threadID); /* location of exception throw */ outStream_writeLocation(&out, JDWP_TypeTag_CLASS, (GET_CLASS_DEBUGGERID(&thisMethod->ofClass->clazz)), getMethodIndex(thisMethod), throwOffset); /* thrown exception */ outStream_writeByte(&out, 'L'); outStream_writeObject(&out, (OBJECT)(unhand(exceptionH))); /* location of catch, or 0 if not caught */ if (catchMethod == NIL) { outStream_writeLocation(&out, 0, 0, 0, 0); } else { outStream_writeLocation(&out, JDWP_TypeTag_CLASS, (GET_CLASS_DEBUGGERID(&catchMethod->ofClass->clazz)), getMethodIndex(catchMethod), catchOffs); } checkEventCount(ep); ep = ep->sendNext; } outStream_sendCommand(&out); handleSuspendPolicy(suspendPolicy, GET_VMTHREAD(cep->threadID), TRUE); END_TEMPORARY_ROOTS }}/*======================================================================== * Function: setEvent_ExceptionCatch() * Overview: * * Interface: * parameters: * re
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -