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

📄 stack.c

📁 debug source code under unix platform.
💻 C
📖 第 1 页 / 共 2 页
字号:
/* Return a handle for the frame pointer at the current point in execution. */staticunsigned long *getframe(void){#if SYSTEM == SYSTEM_DRSNX || SYSTEM == SYSTEM_SOLARIS    ucontext_t c;#endif /* SYSTEM */    unsigned long a;#if SYSTEM == SYSTEM_DRSNX || SYSTEM == SYSTEM_SOLARIS    if (getcontext(&c) == -1)        return NULL;    a = c.uc_mcontext.gregs[R_SP];#else /* SYSTEM */    a = __mp_stackpointer();#endif /* SYSTEM */#if ENVIRON == ENVIRON_64    return (unsigned long *) (a + 0x7FF) + 14;#else /* ENVIRON */    return (unsigned long *) a + 14;#endif /* ENVIRON */}#endif /* ARCH */#endif /* MP_BUILTINSTACK_SUPPORT && MP_LIBRARYSTACK_SUPPORT && TARGET *//* Return a handle for the stack frame at the current point in execution * or the next stack frame in the call stack. */MP_GLOBALint__mp_getframe(stackinfo *p){#if MP_BUILTINSTACK_SUPPORT    void *f;#elif MP_LIBRARYSTACK_SUPPORT#if TARGET == TARGET_UNIX#if SYSTEM == SYSTEM_HPUX    frameinfo f;#elif SYSTEM == SYSTEM_TRU64    char *s;#endif /* SYSTEM */#elif TARGET == TARGET_WINDOWS    jmp_buf j;#endif /* TARGET */#else /* MP_BUILTINSTACK_SUPPORT && MP_LIBRARYSTACK_SUPPORT */#if MP_SIGINFO_SUPPORT    struct sigaction i;#endif /* MP_SIGINFO_SUPPORT */#if (TARGET == TARGET_UNIX && (ARCH == ARCH_IX86 || ARCH == ARCH_M68K || \      ARCH == ARCH_M88K || ARCH == ARCH_POWER || ARCH == ARCH_POWERPC || \      ARCH == ARCH_SPARC)) || ((TARGET == TARGET_WINDOWS || \      TARGET == TARGET_NETWARE) && ARCH == ARCH_IX86)    unsigned long *f;#endif /* TARGET && ARCH */#endif /* MP_BUILTINSTACK_SUPPORT && MP_LIBRARYSTACK_SUPPORT */    int r;    r = 0;#if MP_BUILTINSTACK_SUPPORT    if (p->index == 0)    {        /* We use the macros defined above to fill in the arrays of frame         * pointers and return addresses.  These macros rely on the fact that         * if there are no more frames in the call stack then the builtin         * functions will return NULL.  If this is not the case then the         * library will crash.         */        frameaddresses(p->frames, f, MP_MAXSTACK);        returnaddresses(p->addrs, f, MP_MAXSTACK);    }    if ((p->index++ < MP_MAXSTACK) && (p->frame = p->frames[p->index - 1]))    {        p->addr = p->addrs[p->index - 1];        r = 1;    }    else    {        p->frame = NULL;        p->addr = NULL;        p->index = MP_MAXSTACK;    }#elif MP_LIBRARYSTACK_SUPPORT    /* HP/UX, IRIX, Tru64 and Windows platforms provide a library for     * traversing function call stack frames since the stack frame format     * does not necessarily preserve frame pointers.  On HP/UX this is done     * via a special section which can be read by debuggers.     */#if TARGET == TARGET_UNIX#if SYSTEM == SYSTEM_HPUX    if (p->frame == NULL)    {        __mp_frameinfo(&p->next);        if (U_get_previous_frame(&p->next, &f) == 0)        {            p->next.size = f.size;            p->next.sp = f.sp;            p->next.ps = f.ps;            p->next.pc = f.pc;            p->next.dp = f.dp;        }        else            __mp_memset(&p->next, 0, sizeof(frameinfo));    }    if (p->next.pc && (U_get_previous_frame(&p->next, &f) == 0))    {        p->frame = (void *) p->next.sp;        p->addr = (void *) (p->next.pc & ~3);        p->next.size = f.size;        p->next.sp = f.sp;        p->next.ps = f.ps;        p->next.pc = f.pc;        p->next.dp = f.dp;        r = 1;    }    else    {        p->frame = NULL;        p->addr = NULL;    }#elif SYSTEM == SYSTEM_IRIX || SYSTEM == SYSTEM_TRU64    /* On IRIX and Tru64, the unwind() function may call malloc(), free() and     * some memory operation functions every time it is invoked.  Despite the     * fact that we guard against recursion here, it may slow down execution to     * an unbearable pace, so it might be an idea to remove malloc.c from the     * mpatrol library if you have the option of recompiling all of your     * sources to include mpatrol.h.     */    if (!recursive)    {        recursive = 1;        if (p->frame == NULL)        {#if SYSTEM == SYSTEM_IRIX            exc_setjmp(&p->next);#elif SYSTEM == SYSTEM_TRU64            exc_capture_context(&p->next);#endif /* SYSTEM */            unwind(&p->next, NULL);        }        if (p->next.sc_pc != 0)        {            /* On IRIX, the sigcontext structure stores registers in 64-bit             * format so we must be careful when converting them to 32-bit             * quantities.             */#if SYSTEM == SYSTEM_IRIX            p->frame = (void *) p->next.sc_regs[CXT_SP];#elif SYSTEM == SYSTEM_TRU64            p->frame = (void *) p->next.sc_regs[R_SP];#endif /* SYSTEM */            p->addr = (void *) p->next.sc_pc;#if SYSTEM == SYSTEM_TRU64            /* On Tru64 we cannot reliably unwind the stack from file scope             * initialisation or finalisation functions, or from exception-             * handling support functions.  Unfortunately, this means we must             * look at the names of the calling functions, which is likely to             * fail if the executable file has been stripped.             */            if (((s = __mp_symbol(p->addr)) == NULL) ||                ((strncmp(s, "__INIT_00_add_", 14) != 0) &&                 (strncmp(s, "__FINI_00_remove_", 17) != 0) &&                 (strncmp(s, "__exc_add_", 10) != 0) &&                 (strncmp(s, "__exc_remove_", 13) != 0)))            {#endif /* SYSTEM */                unwind(&p->next, NULL);                r = 1;#if SYSTEM == SYSTEM_TRU64            }            else            {                p->frame = NULL;                p->addr = NULL;            }#endif /* SYSTEM */        }        else        {            p->frame = NULL;            p->addr = NULL;        }        recursive = 0;    }#endif /* SYSTEM */#elif TARGET == TARGET_WINDOWS    if (p->frame == NULL)    {        if (p->first == NULL)        {            setjmp(j);            p->next.AddrPC.Offset = ((_JUMP_BUFFER *) &j)->Eip;            p->next.AddrFrame.Offset = ((_JUMP_BUFFER *) &j)->Ebp;            p->next.AddrStack.Offset = ((_JUMP_BUFFER *) &j)->Esp;        }        else        {            p->next.AddrPC.Offset = ((CONTEXT *) p->first)->Eip;            p->next.AddrFrame.Offset = ((CONTEXT *) p->first)->Ebp;            p->next.AddrStack.Offset = ((CONTEXT *) p->first)->Esp;        }        p->next.AddrPC.Mode = AddrModeFlat;        p->next.AddrFrame.Mode = AddrModeFlat;        p->next.AddrStack.Mode = AddrModeFlat;    }    if (StackWalk(IMAGE_FILE_MACHINE_I386, GetCurrentProcess(),        GetCurrentThread(), &p->next, NULL, NULL, SymFunctionTableAccess,        SymGetModuleBase, NULL) && p->next.AddrReturn.Offset)    {        p->frame = (void *) p->next.AddrFrame.Offset;        p->addr = (void *) p->next.AddrReturn.Offset;        r = 1;    }    else    {        p->frame = NULL;        p->addr = NULL;        __mp_memset(&p->next, 0, sizeof(STACKFRAME));    }#endif /* TARGET */#else /* MP_BUILTINSTACK_SUPPORT && MP_LIBRARYSTACK_SUPPORT */#if (TARGET == TARGET_UNIX && (ARCH == ARCH_IX86 || ARCH == ARCH_M68K || \      ARCH == ARCH_M88K || ARCH == ARCH_POWER || ARCH == ARCH_POWERPC || \      ARCH == ARCH_SPARC)) || ((TARGET == TARGET_WINDOWS || \      TARGET == TARGET_NETWARE) && ARCH == ARCH_IX86)    /* This section is not complete in any way for the OS / processor     * combinations it supports, as it is intended to be as portable as possible     * without writing in assembler.  In particular, optimised code is likely     * to cause major problems for stack traversal on some platforms.     */#if TARGET == TARGET_UNIX#if MP_SIGINFO_SUPPORT    i.sa_flags = 0;    (void *) i.sa_handler = (void *) stackhandler;    sigfillset(&i.sa_mask);    sigaction(SIGBUS, &i, &bushandler);    sigaction(SIGSEGV, &i, &segvhandler);#else /* MP_SIGINFO_SUPPORT */    bushandler = signal(SIGBUS, stackhandler);    segvhandler = signal(SIGSEGV, stackhandler);#endif /* MP_SIGINFO_SUPPORT */    if (setjmp(environment))        __mp_newframe(p, p->first);    else#endif /* TARGET */    {        if (p->frame == NULL)            if (p->first == NULL)#if ARCH == ARCH_IX86 || ARCH == ARCH_M68K                f = (unsigned long *) &p - 2;#elif ARCH == ARCH_M88K                f = (unsigned long *) &p - 4;#elif ARCH == ARCH_POWER || ARCH == ARCH_POWERPC                f = (unsigned long *) &p - 6;#elif ARCH == ARCH_SPARC                f = getframe();#endif /* ARCH */            else                f = (unsigned long *) p->first;        else            f = (unsigned long *) p->next;        if (p->frame = f)        {            p->addr = getaddr(f);            /* We cache the next frame pointer in the call stack since on some             * systems it may be overwritten by another call.             */#if ARCH == ARCH_IX86 || ARCH == ARCH_M68K || ARCH == ARCH_M88K || \    ARCH == ARCH_POWER || ARCH == ARCH_POWERPC#if SYSTEM == SYSTEM_LYNXOS            if (!getaddr((unsigned long *) *f))                p->next = NULL;            else#endif /* SYSTEM */                p->next = (void *) *f;#elif ARCH == ARCH_SPARC            if (p->addr == NULL)                p->next = NULL;            else#if ENVIRON == ENVIRON_64                p->next = (void *) ((unsigned long *) (*f + 0x7FF) + 14);#else /* ENVIRON */                p->next = (void *) ((unsigned long *) *f + 14);#endif /* ENVIRON */#endif /* ARCH */            r = 1;        }    }#if TARGET == TARGET_UNIX#if MP_SIGINFO_SUPPORT    sigaction(SIGBUS, &bushandler, NULL);    sigaction(SIGSEGV, &segvhandler, NULL);#else /* MP_SIGINFO_SUPPORT */    signal(SIGBUS, bushandler);    signal(SIGSEGV, segvhandler);#endif /* MP_SIGINFO_SUPPORT */#endif /* TARGET */#elif TARGET == TARGET_UNIX && ARCH == ARCH_MIPS    /* For the MIPS architecture we perform code reading to determine the     * frame pointers and the return addresses.     */#if MP_SIGINFO_SUPPORT    i.sa_flags = 0;    (void *) i.sa_handler = (void *) stackhandler;    sigfillset(&i.sa_mask);    sigaction(SIGBUS, &i, &bushandler);    sigaction(SIGSEGV, &i, &segvhandler);#else /* MP_SIGINFO_SUPPORT */    bushandler = signal(SIGBUS, stackhandler);    segvhandler = signal(SIGSEGV, stackhandler);#endif /* MP_SIGINFO_SUPPORT */    if (setjmp(environment))        __mp_newframe(p, p->first);    else    {        if (p->frame == NULL)            unwind(&p->next);        if ((p->next.ra) && unwind(&p->next))        {            p->frame = (void *) p->next.sp;            p->addr = (void *) (p->next.ra - 8);            r = 1;        }        else        {            p->frame = NULL;            p->addr = NULL;        }    }#if MP_SIGINFO_SUPPORT    sigaction(SIGBUS, &bushandler, NULL);    sigaction(SIGSEGV, &segvhandler, NULL);#else /* MP_SIGINFO_SUPPORT */    signal(SIGBUS, bushandler);    signal(SIGSEGV, segvhandler);#endif /* MP_SIGINFO_SUPPORT */#endif /* TARGET && ARCH */#endif /* MP_BUILTINSTACK_SUPPORT && MP_LIBRARYSTACK_SUPPORT */    return r;}#ifdef __cplusplus}#endif /* __cplusplus */

⌨️ 快捷键说明

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