📄 frame.c
字号:
char className[256]; char methodSignature[256]; int depth = frameDepth() + offset; int counter = depth; char *methodName = methodName(method); getClassName_inBuffer((CLASS)method->ofClass, className); change_Key_to_MethodSignature_inBuffer(method->nameTypeKey.nt.typeKey, methodSignature); /* Print a bar indicating stack frame depth */ while (--counter >= 0) { fprintf(stdout, "|"); } /* Print name of the class, method name & signature */ fprintf(stdout, " (%ld) %s %s.%s%s ", (long)depth, glyph, className, methodName, methodSignature); /* Print thread id */ fprintf(stdout, "(Thread %lx)\n", (long)CurrentThread); END_ASSERTING_NO_ALLOCATION}/*========================================================================= * FUNCTION: exceptionThrownTracing * OVERVIEW: Print a message indicating that an exception isn't being * caught in the same stack frame that it was called. * INTERFACE: * parameters: exception: Exception being thrown *=======================================================================*/#if UNUSED_CODE/* This isn't currently being used. But it's worth leaving * the definition here, in case we ever want to bring it back. */static voidexceptionThrownTracing(INSTANCE_HANDLE exceptionH) { ASSERTING_NO_ALLOCATION int depth = frameDepth(); char className[256]; getClassName_inBuffer((CLASS)unhand(exceptionH)->ofClass, className); fprintf(stdout, "%lx: (%ld) ", (long)CurrentThread, (long)depth); while (--depth >= 0) { fprintf(stdout, "|"); } fprintf(stdout, " Throwing %s\n", className); END_ASSERTING_NO_ALLOCATION}#endif /* UNUSED_CODE *//*========================================================================= * FUNCTION: exceptionCaughtTracing * OVERVIEW: Print a message indicating that an exception has been * caught in a frame other than the one that threw it. * INTERFACE: * parameters: exception: Exception being thrown * handler: Exception handler *=======================================================================*/static voidexceptionCaughtTracing(THROWABLE_INSTANCE_HANDLE exceptionH, HANDLER handler) { ASSERTING_NO_ALLOCATION int depth = frameDepth(); char className[256]; getClassName_inBuffer((CLASS)unhand(exceptionH)->ofClass, className); fprintf(stdout, "%lx: (%ld) ", (long)CurrentThread, (long)depth); while (--depth >= 0) { fprintf(stdout, "|"); } fprintf(stdout, " Caught %s%s\n", className, handler->exception == 0 ? " (finally)" : ""); END_ASSERTING_NO_ALLOCATION}#endif /* INCLUDEDEBUGCODE *//*========================================================================= * FUNCTION: fillInStackTrace, printExceptionStackTrace * TYPE: internal local function * OVERVIEW: save / print information about the current stack * including the method pointers for each stack frame * INTERFACE (operand stack manipulation): * parameters: an Exception * returns: void *====================================================================*/#if PRINT_BACKTRACEvoid fillInStackTrace(THROWABLE_INSTANCE_HANDLE exceptionH) { ARRAY backtrace; int i; int depth; FRAME thisFp; BYTE* thisIp; /* Can't do much if we are in VM startup... */ if (CurrentThread == NULL) return; /* Get the number of frames that need to be saved less the current frame */ for ( depth = 1, thisFp = getFP(); thisFp->previousIp != KILLTHREAD; depth++, thisFp = thisFp->previousFp) ; /* intentionally empty */ /* We are essentially doing an instantiateArray here, but we don't * want it to throw an error if it runs out of memory. For now, we * have to roll our own, but this may become its own function, someday */ backtrace = (ARRAY)mallocHeapObject(SIZEOF_ARRAY(2 * depth), GCT_ARRAY); unhand(exceptionH)->backtrace = backtrace; if (backtrace != NULL) { ASSERTING_NO_ALLOCATION /* Make sure all headers are cleared. */ memset(backtrace, 0, offsetof(struct arrayStruct, data[0])); backtrace->ofClass = PrimitiveArrayClasses[T_INT]; backtrace->length = depth * 2; thisIp = getIP(); thisFp = getFP(); for (i = 0; i < depth; i++) { backtrace->data[i*2].cellp = (cell*)thisFp->thisMethod; backtrace->data[i*2+1].cell = thisIp - thisFp->thisMethod->u.java.code; thisIp = thisFp->previousIp; thisFp = thisFp->previousFp; } END_ASSERTING_NO_ALLOCATION }}#endif /* PRINT_BACKTRACE */void printExceptionStackTrace(THROWABLE_INSTANCE_HANDLE exceptionH) { #if PRINT_BACKTRACE START_TEMPORARY_ROOTS DECLARE_TEMPORARY_ROOT(ARRAY, backtrace, unhand(exceptionH)->backtrace); DECLARE_TEMPORARY_ROOT(char*, className, NULL); int length = (backtrace == NULL ? 0 : backtrace->length); int i; for (i = 0; i < length; i += 2) { METHOD method = (METHOD)(backtrace->data[i].cellp); char *ptr; className = getClassName((CLASS)method->ofClass); ptr = strchr(className, '/'); /* Replace all slashes in the string with dots */ while (ptr != NULL) { *ptr = '.'; ptr = strchr(ptr + 1, '/'); } fprintf(stdout, "\tat %s.%s(+%ld)\n", className, methodName(method), backtrace->data[i+1].cell); } END_TEMPORARY_ROOTS#else fprintf(stdout, "Stack trace data not available\n");#endif /* PRINT_BACKTRACE */} /*========================================================================= * Stack frame printing and debugging operations *=======================================================================*/#if INCLUDEDEBUGCODE/*========================================================================= * FUNCTION: printFrame() * TYPE: public instance-level function on stack frames * OVERVIEW: Prints the contents of a specific execution stack * frame for debugging purposes. * INTERFACE: * parameters: frame pointer * returns: <nothing> *=======================================================================*/static voidprintFrame(FRAME currentFP, unsigned char *currentIP, cell *currentSP){ METHOD thisMethod = currentFP->thisMethod; unsigned char *prevIP = currentFP->previousIp; FRAME prevFP = currentFP->previousFp; char buffer[256]; int argCount, i; cell* pointer; /* This is ugly, but this gets called during fatal errors, and we * may not have any memory to allocate a className buffer, etc() */ getClassName_inBuffer((CLASS)thisMethod->ofClass, buffer); fprintf(stdout, "Method............: %lx '%s.%s (%s)' \n", (long)thisMethod, buffer, methodName(thisMethod), ((thisMethod->accessFlags & ACC_STATIC) ? "static" : "virtual")); fprintf(stdout, "Stack Chunk.......: %lx\n", (long)currentFP->stack); fprintf(stdout, "Frame Pointer.....: %lx\n", (long)currentFP); if (currentIP == NULL) { fprintf(stdout, "Bytecode..........: %lx\n", (long)thisMethod->u.java.code); } else { fprintf(stdout, "Current IP........: %lx = %lx + offset %ld\n", (long)currentIP, (long)thisMethod->u.java.code, (long)(currentIP - thisMethod->u.java.code)); } fprintf(stdout, "Previous Frame....: %lx\n", (long)prevFP); fprintf(stdout, "Previous IP.......: %lx", (long)prevIP); if (prevFP != NULL) { int offset = prevIP - prevFP->thisMethod->u.java.code; fprintf(stdout, " (offset %d)", offset); } fprintf(stdout, "\n"); fprintf(stdout,"Frame size........: %d (%d arguments, %d local variables)\n", thisMethod->frameSize, thisMethod->argCount, (thisMethod->frameSize - thisMethod->argCount)); /* Print the parameters and local variables */ argCount = thisMethod->argCount; for (i = 0, pointer = FRAMELOCALS(currentFP); pointer < (cell*)currentFP; i++, pointer++) { char *format = (i < argCount) ? "Argument[%d].......: %lx\n" : "Local[%d]..........: %lx\n"; fprintf(stdout, format, i, *pointer); } for (i = 1, pointer = (cell*)(currentFP + 1); pointer <= currentSP; pointer++, i++) { fprintf(stdout,"Operand[%d]........: %lx\n", i, *pointer); }}/*========================================================================= * FUNCTION: printStackTrace() * TYPE: public debugging operation * OVERVIEW: Prints the contents of all the stack frames * for debugging purposes. * INTERFACE: * parameters: <none> * returns: <nothing> * NOTE: This operation destroys all the stack frames * so VM execution must be terminated after printing. *=======================================================================*/static void printStackTraceRange(int lower, int count){ FRAME currentFP = getFP(); unsigned char* currentIP = getIP(); cell * currentSP = getSP(); int upper = lower + count; int i; for (i = 0; currentFP != NULL && i < upper; i++) { if (i >= lower) { printFrame(currentFP, currentIP, currentSP); fprintf(stdout,"\n"); } if (currentFP->previousIp == KILLTHREAD) { break; } currentIP = currentFP->previousIp; currentSP = currentFP->previousSp; currentFP = currentFP->previousFp; }}void printStackTrace(){ printStackTraceRange(0, 1000);}/*========================================================================= * FUNCTION: printExecutionStack() * TYPE: public debugging operation * OVERVIEW: Prints the contents of the whole execution stack * for debugging purposes. * INTERFACE: * parameters: <none> * returns: <nothing> *=======================================================================*/void printExecutionStack(){ cell* i; STACK stack; if (CurrentThread == NULL) { return; } for (i = 0, stack = CurrentThread->stack; stack != NULL; stack = stack->next ) { if (STACK_CONTAINS(stack, getSP())) { i += getSP() - stack->cells + 1; break; } else { i += stack->size; } } fprintf(stdout, "Execution stack contains %ld items: \n", (long)i); for (stack = CurrentThread->stack; stack != NULL; stack = stack->next) { if (STACK_CONTAINS(stack, getSP())) { for (i = stack->cells; i <= getSP(); i++) fprintf(stdout, "%lx \n", *i); break; } else { for (i = stack->cells; i < stack->cells + stack->size; i++) fprintf(stdout, "%lx \n", *i); } } fprintf(stdout, "\n");}#endif /* INCLUDEDEBUGCODE *//*========================================================================= * Exception handler debugging and tracing operations *=======================================================================*/#if INCLUDEDEBUGCODE/*========================================================================= * FUNCTION: printHandler() * TYPE: public instance-level operation * OVERVIEW: Print the contents of the given exception handler * for debugging purposes. * INTERFACE: * parameters: pointer to an exception handler object. * returns: <nothing> *=======================================================================*/static voidprintHandler(HANDLER thisHandler) { fprintf(stdout, "Exception handler at %lx:\n", (long)thisHandler); fprintf(stdout, "\tStart PC..: %ld\n", (long)thisHandler->startPC); fprintf(stdout, "\tEnd PC....: %ld\n", (long)thisHandler->endPC); fprintf(stdout, "\tHandler PC: %ld\n", (long)thisHandler->handlerPC); fprintf(stdout, "\tException.: %ld \n", (long)thisHandler->exception); if (thisHandler->exception == 0) fprintf(stdout, "(finally)\n"); fprintf(stdout, "\n");}/*========================================================================= * FUNCTION: printExceptionHandlerTable() * TYPE: public instance-level operation * OVERVIEW: Print the contents of the given exception handler * table for debugging purposes. * INTERFACE: * parameters: pointer to an exception handler table * returns: <nothing> *=======================================================================*/void printExceptionHandlerTable(HANDLERTABLE handlerTable) { FOR_EACH_HANDLER(thisHandler, handlerTable) printHandler(thisHandler); END_FOR_EACH_HANDLER}#endif /* INCLUDEDEBUGCODE */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -