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

📄 trclib.c

📁 vxworks源码源码解读是学习vxworks的最佳途径
💻 C
📖 第 1 页 / 共 2 页
字号:
/* trcLib.c - i80x86 stack trace library *//* Copyright 1984-1995 Wind River Systems, Inc. */#include "copyright_wrs.h"/*modification history--------------------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 "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 (callAdrs, rtnAdrs, nargs, args)*         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 */    char	name[MAX_SYS_SYM_LEN];	/* string associated with val */    SYM_TYPE	type;			/* type associated with val */    INSTR	*addr;			/* next instruction */    int		stackSave;    FAST INSTR *pc = pRegSet->pc;	/* program counter  */    FAST int *fp = (int *)pRegSet->fpReg;	/* stack frame pointer (A6) */    FAST 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) && ((_func_symFindByValue) != NULL) &&	 ((* _func_symFindByValue) (sysSymTbl, (int) pc, name, 				    &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 */	}    }/************************************************************************** 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    (    FAST int *fp,	/* stack frame pointer (A6) */    INSTR *pc,		/* program counter */    int depth,		/* recursion depth */    FUNCPTR printRtn 	/* routine to print single function call */    )    {    FAST 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 ((*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 */    FAST int nargs,		/* number of arguments in function call */    int *args 			/* pointer to function args */    )    {    FAST int i;    BOOL doingDefault = FALSE;    /* if there is no printErr routine do nothing */

⌨️ 快捷键说明

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