⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 debugger.c

📁 Nucleus_2_kvm_Hello 是kvm移植到Nucleus系统的源代码。。。好东西啊
💻 C
📖 第 1 页 / 共 5 页
字号:
/*  * Copyright (c) 1999-2002 Sun Microsystems, Inc. All Rights Reserved. *  * This software is the confidential and proprietary information of Sun * Microsystems, Inc. ("Confidential Information").  You shall not * disclose such Confidential Information and shall use it only in * accordance with the terms of the license agreement you entered into * with Sun. *  * SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF THE * SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR ANY DAMAGES * SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING * THIS SOFTWARE OR ITS DERIVATIVES. *  * Use is subject to license terms. *//*========================================================================= * KVM *========================================================================= * SYSTEM:    KVM * SUBSYSTEM: Java-level debugger * FILE:      debugger.c * OVERVIEW:  This file defines the Java-level debugger interface for *            KVM based on JPDA (Java Platform Debug Architecture). * AUTHOR:    Jonathan Coles, Sun Labs (summer 2000) *            Bill Pittore, Sun Labs *=======================================================================*//*========================================================================= * Include files *=======================================================================*/#include "global.h"#if ENABLE_JAVA_DEBUGGER /* Extends until the end of the file */#include "thread.h"#ifdef PILOT#include <sys_types.h>#include <netinet_in.h>#endif#ifdef WINDOWS#define WIN32_LEAN_AND_MEAN#define NOMSG#ifdef GCC# include <winsock.h>#else# include <winsock2.h>#endif#endif /* WINDOWS *//*======================================================================== * Definitions and declarations *========================================================================*/#if INCLUDEDEBUGCODE#ifndef PILOT#include <stdarg.h>#endifstatic void printDebuggerInfo(const char *major, const char *minor,                               const char *format,...);static void printEventInfo(const char *format,...);static void printValueFromTag(void *address, unsigned char tag);#define TRACE_DEBUGGER(argList) \        if (tracedebugger) { printDebuggerInfo argList ; }  else #define DEBUGGER_EVENT(argList) \        if (tracedebugger) { printEventInfo argList ; }  else #else#define TRACE_DEBUGGER(argList)#define DEBUGGER_EVENT(argList)#endif /* INCLUDEDEBUGCODE */static void clearEvent(VMEventPtr ep);/*======================================================================== * Variables *========================================================================*/static bool_t resumeOK = FALSE;HASHTABLE debuggerHashTable;ID_HASH_ENTRY bucketFreeList = NULL;WEAKPOINTERLIST debugRoot = NULL;unsigned long *bucketMap = NULL;unsigned long bucketsAllocated;unsigned long uniqueDebuggerID = 1;VMEventPtr eventHead = NIL;EVENTMODIFIER modHead = NIL;struct CE_Modifiers *CE_ModHead = NIL;struct Modifiers *ModHead = NIL;static long requestID = 1;bool_t vmDebugReady;bool_t debuggerActive;bool_t waitOnSuspend;bool_t allThreadsSuspended = FALSE;bool_t suspend;       /* Suspend all threads on VM startup.                        * Set to TRUE by default in main.c.                       */int _method_index_base = 0;short debuggerPort = DEFAULT_DEBUGGER_PORT;long debuggerNotifyList=Dbg_EventKind_NONE;#define GET_VMTHREAD(threadID) (getObjectPtr(threadID) == NULL ? NULL : ((JAVATHREAD)getObjectPtr(threadID))->VMthread)/*======================================================================== * Debugging operations *========================================================================*/#if INCLUDEDEBUGCODE/*======================================================================== * OP Code Lengths used by isLegalOffset() below.  *========================================================================*/static const unsigned char opcodeLengths[] = {     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0 */     1, 1, 1, 1, 1, 1, 2, 3, 2, 3, /* 10 */     3, 2, 2, 2, 2, 2, 1, 1, 1, 1, /* 20 */     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 30 */     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 40 */     1, 1, 1, 1, 2, 2, 2, 2, 2, 1, /* 50 */     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 60 */     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 70 */     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 80 */     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 90 */     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 100 */     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 110 */     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 120 */     1, 1, 3, 1, 1, 1, 1, 1, 1, 1, /* 130 */     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 140 */     1, 1, 1, 3, 3, 3, 3, 3, 3, 3, /* 150 */     3, 3, 3, 3, 3, 3, 3, 3, 3, 2, /* 160 */     0, 0, 1, 1, 1, 1, 1, 1, 3, 3, /* 170 */     3, 3, 3, 3, 3, 5, 0, 3, 2, 3, /* 180 */     1, 1, 3, 3, 1, 1, 0, 4, 3, 3, /* 190 */     5, 5, 1,                      /* 200 - 202 */              3, 3, 3, 3, 3, 3, 3, /* 202 - 209.  Artificial */     3, 3, 3, 0, 3, 3, 3, 5, 3, 3, /* 210.        Artificial */     4, 3, 3, 1                    /* 220 - 223.  Artificial */ };/*======================================================================== * Function:        isLegalOffset() * Overview:        Given a method and an offset, it determines if the  *                  offset is a legal offset into the bytecode of the method.  * Interface: *   parameters:    pointer to thisMethod  *                  long offset  *   returns:       TRUE if it is a legal offset, FALSE otherwise * *=======================================================================*/static bool_t isLegalOffset(METHOD thisMethod, long offset) {     unsigned char *code = thisMethod->u.java.code;     unsigned int codeLength = thisMethod->u.java.codeLength;     unsigned char *expectedCode = &code[offset];     unsigned char *currentCode = code;     if (offset >= (long)codeLength) {         return FALSE;     }     while (currentCode < expectedCode) {         unsigned char token = currentCode[0];         switch(token) {       case TABLESWITCH: {             long low, high;             currentCode = (unsigned char *)((long)(currentCode + 4) & ~3);             low = getAlignedCell(currentCode + 4);             high = getAlignedCell(currentCode + 8);             currentCode += 12 + (high - low + 1) * 4;             break;         }       case LOOKUPSWITCH: {             long pairs;             currentCode = (unsigned char *)((long)(currentCode + 4) & ~3);             pairs = getAlignedCell(currentCode + 4);             currentCode += 8 + pairs * 8;             break;         }       case WIDE:             currentCode += ((currentCode[1] == IINC) ? 6 : 4);             break;         default:             currentCode += opcodeLengths[token];             break;       }     }     return (currentCode == expectedCode);    }#endif /* INCLUDEDEBUGCODE */static void nop(PACKET_INPUT_STREAM_HANDLE inH, PACKET_OUTPUT_STREAM_HANDLE outH){    struct CmdPacket *cmd = &unhand(inH)->packet->type.cmd;    TRACE_DEBUGGER(("Unknown Command", "", "%d/%d", cmd->cmdSet, cmd->cmd));    outStream_setError(outH, JDWP_Error_NOT_IMPLEMENTED);}static void * allocAlignedBytes(long size) {    void *p;#if COMPILER_SUPPORTS_LONG    /*     * mallocBytes allocates a cell sized block which means that     * the address returned is always 4 byte aligned.  We need     * 8 byte aligned so we add 4 more bytes to size then     * re-adjust the address of newMod     */        p = callocPermanentObject(ByteSizeToCellSize((size + 4)));    /* roundup to next 8 byte boundary */    p = (void *)(((unsigned long)p + 7) & ~7);#else        p = callocPermanentObject(ByteSizeToCellSize(size));#endif    return (p);}static void setResumeOK(bool_t val) {    resumeOK = val;}/*======================================================================== * Function:        isValidThread() * Overview:        determines whether a thread actually exists *                   * Interface: *  parameters:     thread *  returns:        bool_t * * Notes: *=======================================================================*/static bool_t isValidThread(THREAD thread){    THREAD tptr;    for (tptr = AllThreads; tptr != NULL; tptr = tptr->nextAliveThread) {         if (tptr == thread) {             return TRUE;        }    }    return FALSE;}/*======================================================================== * Function:        isValidJavaThread() * Overview:        determines whether this Java thread actually exists *                   * Interface: *  parameters:     object to test *  returns:        bool_t * * Notes: *=======================================================================*/static bool_t isValidJavaThread(OBJECT obj){    THREAD tptr;    for (tptr = AllThreads; tptr != NULL; tptr = tptr->nextAliveThread) {         if (tptr->javaThread == (JAVATHREAD)obj) {             return TRUE;        }    }    return FALSE;}static bool_t isValidObject(OBJECT object){    if (object == NULL || object->ofClass == NULL) {         return FALSE;    } else if (!inCurrentHeap(object)) {         CLASS clazz = object->ofClass;        /* These are the only user visible types that don't live in the         * heap.  Anything else is almost certainly a bug.          */        return   clazz == (CLASS)JavaLangClass || clazz == (CLASS)JavaLangString              || clazz == (CLASS)PrimitiveArrayClasses[T_CHAR];    } else {         /* Occasionally, Java instances point to heap values that shouldn't         * be externally visible.  (E.g. Thread's point to an "implementation".)         * Let's make sure the type of the object really is something the         * user ought to know about.         */        GCT_ObjectType type = getObjectType((cell*)object);        return (type == GCT_INSTANCE || type == GCT_ARRAY                  || type == GCT_OBJECTARRAY);    }}static unsigned long debuggerHash(OBJECT p){    return (unsigned long)objectHashCode(p);}static void freeBucket(ID_HASH_ENTRY bucket) {    ID_HASH_ENTRY tmpBucket, *freeBucketPtr, *lastBucketPtr;    unsigned long index;    index = (bucket->key >> DEBUGGER_INDEX_SHIFT) & DEBUGGER_INDEX_MASK;    freeBucketPtr = (ID_HASH_ENTRY *)&debuggerHashTable->bucket[index];    lastBucketPtr = freeBucketPtr;    for (tmpBucket = *freeBucketPtr;        tmpBucket != NULL; tmpBucket = tmpBucket->next) {        if (bucket == tmpBucket) {            *lastBucketPtr = tmpBucket->next;            break;         }         lastBucketPtr = &tmpBucket->next;    }    bucket->next = bucketFreeList;    bucketFreeList = bucket;    bucket->key = 0;}/*======================================================================== * Function:        addToDebugRoot() * Overview:        add this object to the debug root * Interface: *   parameters:    pointer to object *   returns:       index into array * * Notes: *                 The debugRoot contains object references and these *                 references will be updated by the GC since debugRoot is a *                 weak Pointerlist type.  We also keep a parallel array *                 called the bucketMap which contains a pointer to the *                 hash bucket that will contain this entry.  We do this *                 so we can easily re-use buckets since they are allocated *                 from permanent memory.  If we re-use a debugRoot entry *                 (because it was GC'd and NULL'd out) we set the bucket->key *                 value to 0 so that the getObjectID code will notice that *                 this bucket is free and re-use it. *                 Note that classes/objects that are in permanent memory *                 have an ID that is their actual address.  We distinguish *                 between these and transient objects by bit 0 being set in *                 the ID. *=======================================================================*/static unsigned int addToDebugRoot(void *object, ID_HASH_ENTRY bucket){    unsigned long i;    unsigned long length = debugRoot->length;    ID_HASH_ENTRY tmpBucket;    unsigned long *tmpPtr;#if INCLUDEDEBUGCODE        /**      * Note:  debugRoot->data[length - 1] is always empty.     */    if (debugRoot->data[length - 1].cellp != NULL) {         fatalError(KVM_MSG_DEBUG_ROOT_CANNOT_BE_FULL);    }#endif    for (i = 0; ; i++) {         if (debugRoot->data[i].cellp == NULL) {            debugRoot->data[i].cellp = (cell *)object;            if (bucketMap[i] != 0) {                /* This debugRoot entry was freed by the GC, so lets free                  * up the bucket that corresponds to it.                 */                tmpBucket = (ID_HASH_ENTRY)bucketMap[i];#if INCLUDEDEBUGCODE                if (i != tmpBucket->rootIndex)                    fatalError(KVM_MSG_DEBUG_HASHTABLE_INCONSISTENT);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -