📄 dbgtasklib.c
字号:
/* dbgTaskLib.c - Task breakpoint handling *//* Copyright 1997-2002 Wind River Systems, Inc. *//*modification history--------------------01h,19apr02,jhw Prevent breakpoint removal when running in System Mode (SPR 75987).01g,09nov01,jhw Revert WDB_INFO to be inside of WIND_TCB.01f,17oct01,jhw Access WDB_INFO from WIND_TCB pointer pWdbInfo.01e,03feb99,cpd Fix for SPR24102: Added Windview instrumentation when lockCnt is directly decremented, rather than taskUnlock.01d,19jan99,elg Restore PC for MIPS (SPR 24356)01c,21apr98,dbt code cleanup.01b,13mar98,dbt moved _func_wdbIsNowExternal to wdbDbgLib.c (scalability problem).01a,05dec97,dbt written based on wdbTaskBpLib.c.*//*DESCRIPTIONThis library contains routines for task mode debugging. Those routinesare all OS specific and are used by both target shell debugger and WDB debugger in task mode.The facilities provided by routines in this library are : - task deletion and switch handling. - breakpoint exceptions handling. - task continue and task step handling.INTERNALWe should avoid all direct calls to WDB routines without using a pointer.This is necessary because target shell debugger and WDB debugger must beindependant.Since target shell debugger is based on WDB debugger, it is normal to seereferences to some WDB defines (WDB_CTX_LOAD for example) in this file.*/#include "vxWorks.h"#include "taskLib.h"#include "regs.h"#include "stddef.h"#include "sigLib.h"#include "taskLib.h"#include "taskHookLib.h"#include "intLib.h"#include "stdio.h"#include "string.h"#include "wdb/wdbDbgLib.h"#include "private/taskLibP.h"#include "private/kernelLibP.h"/* defines */#define DBG_INFO(p) (&(((WIND_TCB *)(p))->wdbInfo))/* externals */extern FUNCPTR _func_wdbIsNowExternal; /* pointer on wdbIsNowExternal() routine *//* globals */int dbgLockUnbreakable; /* taskLock()'ed tasks are unbreakable */int dbgSafeUnbreakable; /* taskSafe()'ed tasks are unbreakable */int dbgUnbreakableOld; /* unbreakable even if !WDB_ACTION_STOP */FUNCPTR _func_dbgHostNotify = NULL; /* routine to call to notify the host when a breakpoint is encountered */FUNCPTR _func_dbgTargetNotify = NULL; /* routine to call to notify the target when a breakpoint is encountered *//* locals */static int taskTraceData;static int isrTraceData;#if DBG_NO_SINGLE_STEPstatic INSTR * taskNpc; /* next pc of the task */static INSTR taskNpcInstr; /* next instruction of the task */static INSTR * isrNpc; /* next pc at interrrupt level */static INSTR isrNpcInstr; /* next instruction at int. level */#endif /* DBG_NO_SINGLE_STEP *//* forward static declarations */LOCAL void dbgTaskDoIgnore (REG_SET * pRegs);LOCAL void dbgTaskDoneIgnore (REG_SET * pRegs);LOCAL void dbgTaskSwitch (WIND_TCB * pOldTcb, WIND_TCB * pNewTcb);LOCAL void dbgTaskDeleteHook (WIND_TCB * pTcb);LOCAL void dbgTaskBpInstall (int tid);LOCAL BOOL dbgBrkIgnoreDefault (void);/******************************************************************************** dbgTaskBpHooksInstall - install tasking breakpoint hooks** This routine installs breakpoint hooks. One for task switch, one for* task deletion and one for modification of task flags.** RETURNS : N/A.** NOMANUAL*/ void dbgTaskBpHooksInstall ( void ) { static BOOL dbgTaskBpHooksInstalled = FALSE; if (!dbgTaskBpHooksInstalled) { /* task switch hook */ taskSwitchHookAdd ((FUNCPTR) dbgTaskSwitch); /* task delete hook */ taskDeleteHookAdd ((FUNCPTR) dbgTaskDeleteHook); /* set break remove/install hook routine for taskOptionsSet */ taskBpHookSet ((FUNCPTR) dbgTaskBpInstall); dbgTaskBpHooksInstalled = TRUE; } }/********************************************************************************* dbgTaskCont - Handle a continue request** The dbgTaskCont() function is used to continue a task.** RETURNS : * WDB_ERR_INVALID_CONTEXT if the task is not suspended or * if we can't resume it. OK otherwise.** NOMANUAL*/STATUS dbgTaskCont ( UINT32 taskId /* Id of task to continue */ ) { if (!taskIsSuspended(taskId)) return (WDB_ERR_INVALID_CONTEXT); /* * Check if there is a breakpoint at current pc or if the last * encountered breakpoint still exist (needed for data access * breakpoints). */ taskLock (); /* LOCK PREEMPTION */ if ((wdbDbgBpFind ((INSTR *)(((WIND_TCB *)taskId)->regs.reg_pc), taskId) == OK) || (wdbDbgBpFind ((INSTR *)(DBG_INFO(taskId)->bpAddr), taskId) == OK)) { DBG_INFO(taskId)->wdbState |= WDB_STEP_OVER; } taskUnlock (); /* UNLOCK PREEMPTION */ if (taskResume (taskId) != OK) return (WDB_ERR_INVALID_CONTEXT); return (OK); }/********************************************************************************* dbgTaskStep - Handle a step request** The dbgTaskStep() function is used to step a task.** RETURNS : * WDB_ERR_INVALID_CONTEXT if the task is not suspended or * if we can't resume it. OK otherwise.** NOMANUAL*/STATUS dbgTaskStep ( UINT32 contextId, /* Id of task to step */ UINT32 startAddr, /* start address */ UINT32 endAddr /* end address */ ) { if (!taskIsSuspended(contextId)) return (WDB_ERR_INVALID_CONTEXT); if (startAddr == 0 && endAddr == 0) DBG_INFO(contextId)->wdbState |= WDB_STEP; else { if (DBG_INFO(contextId)->wdbState & WDB_QUEUED) return (WDB_ERR_INVALID_CONTEXT); DBG_INFO(contextId)->wdbState |= WDB_STEP_RANGE; DBG_INFO(contextId)->wdbEvtList.wdb1 = (void *) startAddr; DBG_INFO(contextId)->wdbEvtList.wdb2 = (void *) endAddr; } if (taskResume (contextId) != OK) return (WDB_ERR_INVALID_CONTEXT); return (OK); }/******************************************************************************** dbgTaskDeleteHook - remove task-specific BP's when a task exits** This hook removes the task-specific breakpoints when a task exits.** RETURNS : N/A** NOMANUAL*/ LOCAL void dbgTaskDeleteHook ( WIND_TCB * pTcb /* TCB of the deleted task */ ) { dll_t * pDll; dll_t * pDllNext; int level; /* remove events still queued in the task TCB */ level = intLock (); if (DBG_INFO(pTcb)->wdbState & WDB_QUEUED) { DBG_INFO(taskIdCurrent)->wdbState &= ~WDB_QUEUED; dll_remove ((dll_t *)&(DBG_INFO(pTcb)->wdbEvtList)); } intUnlock (level); /* delete task specific breakpoints */ taskLock (); /* LOCK PREEMPTION */ for (pDll = dll_head(&bpList); pDll != dll_end(&bpList); pDll = pDllNext) { pDllNext = dll_next(pDll); /* We remove only breakpoints specific to deleted task. */ if (BP_BASE(pDll)->bp_task == (int) pTcb) wdbDbgBpRemove (BP_BASE(pDll)); } taskUnlock (); /* UNLOCK PREEMPTION */ }/******************************************************************************** dbgTaskBpInstall - install breakpoints for the current task** This routine installs BP's for the new task and remove ones for * the old task.** RETURNS : N/A.** NOMANUAL*/ LOCAL void dbgTaskBpInstall ( int tid /* id of the task */ ) { dll_t * pDll; BOOL stepping; /* task is stepping */ BOOL breakable; /* task is breakable */ BOOL bpi; /* breakpoint is installed */ int level; /* interrupt lock level */ BRKPT * pBp; WIND_TCB * pTcb = (tid == 0 ? taskIdCurrent : (WIND_TCB *)tid);#if DBG_HARDWARE_BP DBG_REGS dbgRegs;#endif /* do not install or remove breakpoints when in system mode */ if ((_func_wdbIsNowExternal != NULL) && _func_wdbIsNowExternal()) return; /* clean local debug register buffer and the debug registers */#if DBG_HARDWARE_BP memset (&dbgRegs, 0, sizeof (DBG_REGS)); wdbDbgRegsClear ();#endif /* DBG_HARDWARE_BP */ /* set local flags */ stepping = DBG_INFO(pTcb)->wdbState & WDB_STEPING; breakable = !(pTcb->options & VX_UNBREAKABLE); /* * Iterate through the breakpoint list and remove/install the * breakpoints appropriate to the current task. */ for (pDll = dll_head(&bpList); pDll != dll_end(&bpList); pDll = dll_next(pDll)) { pBp = BP_BASE(pDll); /* should the breakpoint be installed? */ bpi = !(stepping || ((pBp->bp_task != BP_ANY_TASK) && (pBp->bp_task != (int)pTcb)) || ((!breakable) && (pBp->bp_action & WDB_ACTION_STOP)) || ((!breakable) && dbgUnbreakableOld)); /* does the current BP state match the requested BP state? */ if ((pBp->bp_flags & BP_INSTALLED) != bpi) { level = intLock (); if (bpi) { pBp->bp_flags |= BP_INSTALLED; /* install software breakpoint only */ if ((pBp->bp_flags & BRK_HARDWARE) == 0) usrBreakpointSet (pBp->bp_addr, DBG_BREAK_INST); } else { /* remove software breakpoint only */ if ((pBp->bp_flags & BRK_HARDWARE) == 0) usrBreakpointSet (BP_BASE(pDll)->bp_addr, BP_BASE(pDll)->bp_instr); BP_BASE(pDll)->bp_flags &= ~BP_INSTALLED; } intUnlock(level); }#if DBG_HARDWARE_BP /* fill local dbgRegs structure with the HW breakpoint info */ if (bpi && (pBp->bp_flags & BRK_HARDWARE)) wdbDbgHwBpSet (&dbgRegs, pBp->bp_flags & BRK_HARDMASK, (UINT32) pBp->bp_addr);#endif /* DBG_HARDWARE_BP */ }#if DBG_HARDWARE_BP /* * Set CPU debug registers with the new info. * This structure contains only hardware breakpoints for the new task. */ wdbDbgRegsSet (&dbgRegs); /* set debug registers. */#endif /* DBG_HARDWARE_BP */ }/********************************************************************************* dbgTaskSwitch - system task switch routine** Tasking breakpoints are set during context switches using this routine.* This allows breakpoints to not affect certain tasks.** RETURNS : N/A.** NOMANUAL*/LOCAL void dbgTaskSwitch ( WIND_TCB * pOldTcb, /* pointer to tcb of switch-from task */ WIND_TCB * pNewTcb /* pointer to tcb of switch-to task */ ) { /* * Don't do task BP switch hook if the agent is in system mode. * This test is only usefull if we use WDB breakpoints. */ if ((_func_wdbIsNowExternal != NULL) && _func_wdbIsNowExternal()) return; /* perform some cleanup on the old task */ if (TASK_ID_VERIFY(pOldTcb) == OK) /* suicide runs delete hook 1st */ { if (DBG_INFO(pOldTcb)->wdbState & WDB_CLEANME) { taskSuspend((int) pOldTcb); taskRegsSet((int) pOldTcb, DBG_INFO(pOldTcb)->wdbRegisters);#if CPU_FAMILY==MC680X0 pOldTcb->foroff = 0;#endif /* CPU_FAMILY==MC680X0 */ DBG_INFO(pOldTcb)->wdbState &= ~WDB_CLEANME; } if (DBG_INFO(pOldTcb)->wdbState & WDB_STEPING) {#if DBG_NO_SINGLE_STEP usrBreakpointSet (taskNpc, taskNpcInstr);#endif /* DBG_NO_SINGLE_STEP */ wdbDbgTraceModeClear (&pOldTcb->regs, taskTraceData); } } /* * If we are stepping, remove all BP's and set trace mode. * * else, if we are not stepping, remove breakpoints for the old task and * install them for new task. */ if (DBG_INFO(pNewTcb)->wdbState & WDB_STEPING) { /* remove all the breakpoints for this task */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -