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

📄 trclib.c

📁 VxWorks BSP框架源代码包含头文件和驱动
💻 C
📖 第 1 页 / 共 2 页
字号:
/* trcLib.c - PowerPC stack trace library *//* Copyright 1984-1994 Wind River Systems, Inc. */#include "copyright_wrs.h"/*modification history--------------------02b,27feb96,ms   reworked findFuncStart.02a,01feb96,ms   rewritten.01c,16jan95,caf  disabled stack trace support for now.01b,05dec94,caf  added cast to trcStack().01a,07nov94,yao  written.*//*This module provides the 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 "symLib.h"#include "taskLib.h"#include "regs.h"#include "string.h"#include "private/funcBindP.h"#include "dbgLib.h"#include "sysSymTbl.h"#include "vxLib.h"/* definitions */#define MAX_TRACE_DEPTH	80	/* maximum stack frames to trace */#define MAX_SCAN_DEPTH	250	/* maximum distance to scan text */#define MAX_PROLOGUE_SIZE 20	/* maximum size of function prologue */#define FP_FROM_STACK(sp)	 (*(char **)(sp))#define RETURN_PC_FROM_STACK(sp) (*(INSTR **)((sp) + 4))#define BOGUS_SP(sp,low,high)	 (((int)(sp) % 8) || ((sp) < (low)) || \				  ((sp) > (high)) || (sp == 0))#define BOGUS_PC(pc, junk)	 (vxMemProbe((char *)(pc), VX_READ, 4, \				  (char *)&(junk)) == ERROR)/* some dissassembly macros */#define INST_LWZX_SP		_OP(31, 55) | (1 << 21)#define INST_LWZUX_SP		_OP(31, 23) | (1 << 21)#define INST_LWZX_SP_MASK	0xffe007fe#define INST_LWZ_SP_MASK	0xffe00000#define STW(reg)	((36 << 26) | ((reg) << 21))#define STW_REG_MASK	0xffe00000/* globals */int trcDefaultArgs = 0;			/* default # of args to print */int trcScanDepth = MAX_SCAN_DEPTH;/* forward declarations */static int	trcGetArgs (INSTR *procAddr, char *sp, int *args);static INSTR *	trcFindFuncStart (INSTR *pc, INSTR *returnPc);static void	trcDefaultPrint (INSTR *callAdrs, INSTR *funcAdrs, 			int nargs, int *args);static void	trcStackLvl (INSTR *pc, INSTR *returnPc, char *sp, char *fp,			char *stackBottom, int depth, FUNCPTR printRtn);static STATUS	trcInfoGet (int tid, REG_SET * pRegs, INSTR ** pPc,			INSTR ** pReturnPc, char ** pSp, char ** pFp);/********************************************************************************* 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 this, is provided* by tt() in dbgLib.* * The routine prints a list of the nested routine calls that are on the stack,* showing each routine call with its parameters.** The stack being traced should be quiescent.  The caller should avoid tracing* its own stack.** PRINT ROUTINE* 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 5* .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 is used that prints out just* the call address, function address, and arguments as hexadecimal values.** CAVEAT* There is no way to determine the function arguments unless the* code is compiled with debugging (e.g., "-gdwarf).** 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) NULL, tid);** .CE** RETURNS: N/A** SEE ALSO: tt()* * NOMANUAL*/void trcStack    (    REG_SET * pRegs,	/* general purpose registers */    FUNCPTR printRtn,	/* routine to print single function call */    int     tid         /* task's id */    )    {    char *stackBottom = taskTcb (tid)->pStackBase;    char *sp;			/* current stack pointer */    char *fp;			/* frame pointer (previous sp) */    INSTR *pc;			/* current program counter */    INSTR *returnPc;		/* return address */    /* get info on the top level stack frame */    if (trcInfoGet (tid, pRegs, &pc, &returnPc, &sp, &fp) == ERROR)	{	if (_func_printErr != NULL)	    _func_printErr ("trcStack aborted: error in top frame\n");	return;	}    /* use default print routine if none specified */    if (printRtn == NULL)	printRtn = (FUNCPTR) trcDefaultPrint;    /* do the recursive stack trace. */    trcStackLvl (pc, returnPc, sp, fp, stackBottom, 0, printRtn);    }/************************************************************************** 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.*/static void trcStackLvl    (    INSTR *pc,		/* current program counter location */    INSTR *returnPc,	/* return address */    char *sp,		/* stack pointer */    char *fp,		/* frame pointer (previous stack pointer) */    char *stackBottom,	/* effective base of task's stack */    int depth,		/* recursion depth */    FUNCPTR printRtn 	/* routine to print single function call */    )    {    char *	prevFp = NULL;    INSTR *	prevReturnPc;    int		args[MAX_TASK_ARGS];    INSTR *	procAddr;    int		nArgs;    /* recursive trace if depth not maxed and framepointer is valid */    if (depth < MAX_TRACE_DEPTH)	{	prevFp = FP_FROM_STACK(fp);	if (BOGUS_SP (prevFp, fp, stackBottom))	    return;	prevReturnPc = RETURN_PC_FROM_STACK(prevFp);	if (!BOGUS_PC (prevReturnPc, procAddr))	    trcStackLvl (returnPc, prevReturnPc, fp, prevFp, stackBottom,			 depth+1, printRtn);	}    /* get the current routine's starting address */    procAddr = trcFindFuncStart (pc, returnPc);    /* get the function arguments */    nArgs = trcGetArgs (procAddr, sp, args);    (* printRtn) (returnPc, procAddr, nArgs, args);    }/********************************************************************************* 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.*/static 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 ix;    BOOL doingDefault = FALSE;    if (!_func_printErr)	return;    /* print call address and function address */    _func_printErr ("%6x: %x (", callAdrs, funcAdrs);    /* if no args are specified, print out default number (see doc at top) */    if ((nargs == 0) && (trcDefaultArgs != 0))	{	doingDefault = TRUE;	nargs = trcDefaultArgs;	_func_printErr ("[");	}    /* print args */    for (ix = 0; ix < nargs; ++ix)	{	if (ix != 0)	    _func_printErr (", ");	_func_printErr ("%x", args[ix]);	}    if (doingDefault)	_func_printErr ("]");    _func_printErr (")\n");    }/******************************************************************************** trcFindFuncStart - get starting address of a procedure.** Given a "pc" value, determine the address of the procedure* containing that pc.* We try several methods until one succeeds.* 1) First check the returnPc to see if we got to the current proc* via a branch instruction. If so we can determine the procedure* address accuratly.* 2) If there is no branch instruction found, scan backwards up to* trcScanDepth bytes looking for a "stwu sp, xxx(sp)" instruction,* and assume that instruction is the proc entry.** RETURNS: The starting address of the procedure, or NULL if it couldn't* be found.

⌨️ 快捷键说明

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