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

📄 trclib.c

📁 VXWORKS源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* trcLib.c - i80x86 stack trace library *//* Copyright 1984-2001 Wind River Systems, Inc. */#include "copyright_wrs.h"/*modification history--------------------01f,16jan02,pai  replaced obsolete symFindByValue (_func_symFindByValue) with                 symByValueFind.  Removed FAST variable qualifier.                 Cleaned up formatting and updated copyright for T2.2.01e,12may95,p_m  adapted to support host based tt().01d,26oct94,hdn  added a MAX_LOOPCOUNT to avoid infinite loop.01c,09dec93,hdn  added a forward declaration of trcCountArgs().                 commented out trcFollowJmp(pc) in trcFindFuncStart().01b,01jun93,hdn  added third parameter tid to trcStack().                 updated to 5.1.                  - changed functions to ansi style                  - changed VOID to void                  - changed copyright notice01a,16jul92,hdn  written based on TRON version.*//*This module provides a routine, trcStack(), which traces a stackgiven the current frame pointer, stack pointer, and program counter.The resulting stack trace lists the nested routine calls and their arguments.This module provides the low-level stack trace facility.A higher-level symbolic stack trace, implemented on top of this facility,is provided by the routine tt() in dbgLib.SEE ALSO: dbgLib, tt(),.pG "Debugging"*/#include "vxWorks.h"#include "regs.h"#include "stdio.h"#include "stdlib.h"#include "symLib.h"#include "sysSymTbl.h"#include "private/funcBindP.h"#define MAX_TRACE_DEPTH       40  /* max number of levels of stack to trace */#define MAX_LOOPCOUNT        128  /* max loop count *//* instruction patterns and masks */#define ADDI08_0                0x83#define ADDI08_1                0xc4#define ADDI32_0                0x81#define ADDI32_1                0xc4#define LEAD08_0                0x8d#define LEAD08_1                0x64#define LEAD08_2                0x24#define LEAD32_0                0x8d#define LEAD32_1                0xa4#define LEAD32_2                0x24#define JMPD08                  0xeb#define JMPD32                  0xe9#define ENTER                   0xc8#define PUSH_EBP                0x55#define MOV_ESP0                0x89#define MOV_ESP1                0xe5#define LEAVE                   0xc9#define RET                     0xc3#define RETADD                  0xc2#define CALL_DIR                0xe8#define CALL_INDIR0             0xff#define CALL_INDIR1             0x10#define ADDI08_0_MASK           0xff#define ADDI08_1_MASK           0xff#define ADDI32_0_MASK           0xff#define ADDI32_1_MASK           0xff#define LEAD08_0_MASK           0xff#define LEAD08_1_MASK           0xff#define LEAD08_2_MASK           0xff#define LEAD32_0_MASK           0xff#define LEAD32_1_MASK           0xff#define LEAD32_2_MASK           0xff#define JMPD08_MASK             0xff#define JMPD32_MASK             0xff#define ENTER_MASK              0xff#define PUSH_EBP_MASK           0xff#define MOV_ESP0_MASK           0xff#define MOV_ESP1_MASK           0xff#define LEAVE_MASK              0xff#define RET_MASK                0xff#define RETADD_MASK             0xff#define CALL_DIR_MASK           0xff#define CALL_INDIR0_MASK        0xff#define CALL_INDIR1_MASK        0x38#define DSM(addr,inst,mask)     ((*(addr) & (mask)) == (inst))/* globals */int trcDefaultArgs = 5;         /* default # of args to print if trc                                 * can't figure out how many *//* forward declarations */LOCAL INSTR * trcFindCall (INSTR * returnAdrs);LOCAL INSTR * trcFindFuncStart (int * fp, INSTR * pc);LOCAL INSTR * trcFindDest (INSTR * callAdrs);LOCAL INSTR * trcFollowJmp (INSTR * addr);LOCAL void    trcDefaultPrint (INSTR * callAdrs, INSTR * funcAdrs, int nargs,                               int * args);LOCAL void    trcStackLvl (int * fp, INSTR * pc, int depth, FUNCPTR printRtn);LOCAL int     trcCountArgs (INSTR * returnAdrs);/********************************************************************************* trcStack - print a trace of function calls from the stack** This routine provides the low-level stack trace function.  A higher-level* symbolic stack trace, built on top of trcStack(), is provided by tt() in* dbgLib.** This routine prints a list of the nested routine calls that are on the* stack, showing each routine with its parameters.** The stack being traced should be quiescent.  The caller should avoid* tracing its own stack.** PRINT ROUTINE* In order to allow symbolic or alternative printout formats, the call to* this routine includes the <printRtn> parameter, which specifies a* user-supplied routine to be called at each nesting level to print out the* routine name and its arguments.  This routine should be declared as* follows:* .ne 7* .CS*     void printRtn*         (*         INSTR *  callAdrs,  /@ address from which routine was called @/*         int      rtnAdrs,   /@ address of routine called             @/*         int      nargs,     /@ number of arguments in call           @/*         int *    args       /@ pointer to arguments                  @/*         )* .CE* If <printRtn> is NULL, a default routine will be used that prints out just* the call address, the function address, and the arguments as hexadecimal* values.** CAVEAT* In order to do the trace, a number of assumptions are made.  In general,* the trace will work for all C language routines and for assembly language* routines that start with an PUSH %EBP MOV %ESP %EBP instruction.  Most * VxWorks assembly language routines include PUSH %EBP MOV %ESP %EBP * instructions for exactly this reason.* However, routines written in other languages, strange entries into* routines, or tasks with corrupted stacks can confuse the trace.  Also,* all parameters are assumed to be 32-bit quantities, therefore structures* passed as parameters will be displayed as a number of long integers.** EXAMPLE* The following sequence can be used* to trace a VxWorks task given a pointer to the task's TCB:* .CS* REG_SET regSet;        /@ task's data registers @/** taskRegsGet (taskId, &regSet);* trcStack (&regSet, (FUNCPTR)printRtn, tid);* .CE** SEE ALSO: tt()** NOMANUAL*/void trcStack    (    REG_SET * pRegSet,        /* pointer to register set */    FUNCPTR   printRtn,       /* routine to print single function call */    int       tid             /* task's id */    )    {    int       val;            /* address gotten from symbol table */    SYM_TYPE  type;           /* type associated with val */    INSTR *   addr;           /* next instruction */    int       stackSave;    char *    pName = NULL;   /* string associated with val */    INSTR *   pc    = pRegSet->pc;             /* program counter */    int *     fp    = (int *)pRegSet->fpReg;   /* stack frame pointer (EBP) */    int *     sp    = (int *)pRegSet->spReg;   /* stack pointer */    /* use default print routine if none specified */    if (printRtn == NULL)        printRtn = (FUNCPTR)trcDefaultPrint;    /*     * if the current routine doesn't have a stack frame, then we fake one     * by putting the old one on the stack and making fp point to that;     * we KNOW we don't have a stack frame in a few restricted but useful     * cases:     *  1) we are at a PUSH %EBP MOV %ESP %EBP or RET or ENTER instruction,     *  2) we are the first instruction of a subroutine (this may NOT be     *     a PUSH %EBP MOV %ESP %EBP instruction with some compilers)     */    addr = trcFollowJmp (pc);    if ((DSM(addr,   PUSH_EBP, PUSH_EBP_MASK) &&          DSM(addr+1, MOV_ESP0, MOV_ESP0_MASK) &&         DSM(addr+2, MOV_ESP1, MOV_ESP1_MASK)) ||        (DSM(addr,   ENTER,    ENTER_MASK))    ||        (DSM(addr,   RET,      RET_MASK))      ||        (DSM(addr,   RETADD,   RETADD_MASK))   ||        ((sysSymTbl != NULL) &&         (symByValueFind (sysSymTbl, (UINT) pc, &pName, &val, &type) == OK) &&         (val == (int) pc)))        {        /* no stack frame - fake one */        stackSave = *(sp - 1);      /* save value we're going to clobber */        *(sp - 1) = (int)fp;        /* make new frame pointer by */                                    /* sticking old one on stack */        fp = sp - 1;                /* and pointing to it */        trcStackLvl (fp, pc, 0, printRtn);        /* do stack trace */        *(sp - 1) = stackSave;                    /* restore stack */        }    else if ((DSM(addr-1, PUSH_EBP, PUSH_EBP_MASK) &&               DSM(addr,   MOV_ESP0, MOV_ESP0_MASK) &&              DSM(addr+1, MOV_ESP1, MOV_ESP1_MASK)))        {        fp = sp;        trcStackLvl (fp, pc, 0, printRtn);        /* do stack trace */        }    else        {        trcStackLvl (fp, pc, 0, printRtn);        /* do stack trace */        }    if (pName != NULL)        {        free (pName);  /* new API requires this */        }    }/************************************************************************** trcStackLvl - recursive stack trace routine** This routine is recursive, being called once for each level of routine* nesting.  The maximum recursion depth is limited to 40 to prevent* garbage stacks from causing this routine to continue unbounded.* The "depth" parameter on the original call should be 0.*/LOCAL void trcStackLvl    (    int *    fp,        /* stack frame pointer (EBP) */    INSTR *  pc,        /* program counter */    int      depth,     /* recursion depth */    FUNCPTR  printRtn   /* routine to print single function call */    )    {    INSTR *  returnAdrs;    if (fp == NULL)        return;        /* stack is untraceable */    returnAdrs = (INSTR *) *(fp + 1);    /* handle oldest calls first, up to MAX_TRACE_DEPTH of them */    if (((void *)*fp != NULL) && (depth < MAX_TRACE_DEPTH))        {        trcStackLvl ((int *) *fp, returnAdrs, depth + 1, printRtn);        }    (* printRtn) (trcFindCall (returnAdrs), trcFindFuncStart (fp, pc),                  trcCountArgs (returnAdrs), fp + 2);    }/********************************************************************************* trcDefaultPrint - print a function call** This routine is called by trcStack to print each level in turn.** If nargs is specified as 0, then a default number of args (trcDefaultArgs)* is printed in brackets ("[..]"), since this often indicates that the* number of args is unknown.*/LOCAL void trcDefaultPrint    (    INSTR * callAdrs,   /* address from which function was called */    INSTR * funcAdrs,   /* address of function called */    int     nargs,      /* number of arguments in function call */    int *   args        /* pointer to function args */    )    {    int     i;    BOOL    doingDefault = FALSE;    /* if there is no printErr routine do nothing */    if (_func_printErr == NULL)        return;

⌨️ 快捷键说明

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