📄 dbglib.c
字号:
else action = WDB_ACTION_STOP | WDB_ACTION_NOTIFY; /* add new breakpoint */ if (dbgBrkAdd (addr, tid, 0, action, count, NULL, 0) == NULL) { printErr (DBG_BKPT_TBL_FULL); retVal = ERROR; goto done; }done: TEXT_LOCK(addr); return (retVal); }/******************************************************************************** e - set or display eventpoints (WindView)** This routine sets "eventpoints"--that is, breakpoint-like instrumentation* markers that can be inserted in code to generate and log an event for use* with WindView. Event logging must be enabled with wvEvtLogEnable() for* the eventpoint to be logged.** <eventId> selects the evenpoint number that will be logged: it is in * the user event ID range (0-25536).** If <addr> is NULL, then all eventpoints and breakpoints are displayed.* If <taskNameOrId> is 0, then this event is logged in all tasks.* The <evtRtn> routine is called when this eventpoint is hit. If <evtRtn>* returns OK, then the eventpoint is logged; otherwise, it is ignored.* If <evtRtn> is a NULL pointer, then the eventpoint is always logged.** Eventpoints are exactly like breakpoints (which are set with the b()* command) except in how the system responds when the eventpoint is hit. An* eventpoint typically records an event and continues immediately (if* <evtRtn> is supplied, this behavior may be different). Eventpoints cannot* be used at interrupt level.** To delete an eventpoint, use bd().** RETURNS* OK, or ERROR if <addr> is odd or nonexistent in memory, or if the* breakpoint table is full.** SEE ALSO: wvEvent()*/STATUS e ( INSTR * addr, /* where to set eventpoint, or */ /* 0 means display all eventpoints */ event_t eventId, /* event ID */ int taskNameOrId, /* task affected; 0 means all tasks */ FUNCPTR evtRtn, /* function to be invoked; */ /* NULL means no function is invoked */ int arg /* argument to be passed to <evtRtn> */ ) { int tid = 0; /* task ID */ int val; /* temporary buffer */ int retVal = OK; /* return value */ EVT_CALL_ARGS * pEvtCall; /* structure to pass arguments */ if (dbgInstall () != OK) return (ERROR); if (taskNameOrId != 0) tid = taskIdFigure (taskNameOrId); /* convert to task id */ if (tid == ERROR) { printErr (DBG_TASK_NOT_FOUND); return (ERROR); } /* NULL address means show all breakpoints */ if (addr == NULL) { dbgBrkDisplay (); return (OK); } /* if text segment protection turned on, first write enable the page */ TEXT_UNLOCK(addr); /* check validity of breakpoint address */ if (!ALIGNED ((int) addr, DBG_INST_ALIGN) || (vxMemProbe ((char *)addr, VX_READ, sizeof(INSTR), (char *)&val) != OK) || (vxMemProbe ((char *)addr, VX_WRITE, sizeof(INSTR), (char *)&val) != OK)) { printErr (DBG_ILL_EVTPT_ADDR, (int)addr); retVal = ERROR; goto done; } /* * The runtime callout, dbgE, requires three parameters (an event number, * and a conditioning routine and argument). However the breakpoints * only support passing one argument to the callout. So here we allocate * a structure and pass it's address to the callout. * XXX - this creates a memory leak of 12 bytes. * We need to store the address of the structure with the eventpoint, * and have the breakpoint delete routines check and free the memory. */ if ((pEvtCall = (EVT_CALL_ARGS *) malloc (sizeof (EVT_CALL_ARGS))) == NULL) { retVal = ERROR; goto done; } pEvtCall->evtRtn = evtRtn; pEvtCall->evtRtnArg = arg; pEvtCall->eventId = eventId; /* add new breakpoint */ if (dbgBrkAdd (addr, tid, BP_EVENT, WDB_ACTION_CALL, 0, (FUNCPTR) dbgE, (int) pEvtCall) == NULL) { printErr (DBG_EVTPT_TBL_FULL); retVal = ERROR; goto done; }done: TEXT_LOCK(addr); return (retVal); }#if DBG_HARDWARE_BP/******************************************************************************** bh - set a hardware breakpoint** This routine is used to set a hardware breakpoint. If the architecture* allows it, this function will add the breakpoint to the list of breakpoints* and set the hardware breakpoint register(s). For more information, see the* manual entry for b().** NOTE* The types of hardware breakpoints vary with the architectures. Generally,* a hardware breakpoint can be a data breakpoint or an instruction breakpoint.** RETURNS* OK, or ERROR if <addr> is illegal or the hardware breakpoint table is* full.** SEE ALSO: b(),* .pG "Target Shell"*/STATUS bh ( INSTR * addr, /* where to set breakpoint, or */ /* 0 = display all breakpoints */ int access, /* access type (arch dependant) */ int task, /* task for which to set breakboint, */ /* 0 = set all tasks */ int count, /* number of passes before hit */ BOOL quiet /* TRUE = don't print debugging info, */ /* FALSE = print debugging info */ ) { int tid = 0; BRKPT * pBp; DBG_REGS dbgRegs; dll_t * pDll; int action; int status; if (dbgInstall () != OK) return (ERROR); if (task != 0) tid = taskIdFigure (task); /* convert to task id */ if (tid == ERROR) { printErr (DBG_TASK_NOT_FOUND); return (ERROR); } /* 0 address means show all breakpoints */ if (addr == NULL) { dbgBrkDisplay (); return (OK); } /* check validity of hardware breakpoint address */ if (wdbDbgHwAddrCheck ((UINT32) addr, access, (FUNCPTR) vxMemProbe) != OK) { printErr (DBG_ILL_BKPT_ADDR, (int)addr); return (ERROR); } /* clean dbgRegs structure */ memset (&dbgRegs, 0, sizeof (DBG_REGS)); /* fill dbgRegs structure */ taskLock (); /* LOCK PREEMPTION */ for (pDll = dll_head(&bpList); pDll != dll_end(&bpList); pDll = dll_next(pDll)) { pBp = BP_BASE(pDll); /* check if found breakpoint is applicable to current task */ if ((pBp->bp_task == ALL) || (task == ALL) || (pBp->bp_task == task)) { if (pBp->bp_flags & BRK_HARDWARE) { if (wdbDbgHwBpSet (&dbgRegs, pBp->bp_flags & BRK_HARDMASK, (UINT32) pBp->bp_addr) != OK) { printErr (DBG_HW_BKPT_REGS_FULL); taskUnlock (); /* UNLOCK PREEMPTION */ return (ERROR); } } } } taskUnlock (); /* UNLOCK PREEMPTION */ if (quiet) action = WDB_ACTION_STOP; else action = WDB_ACTION_STOP | WDB_ACTION_NOTIFY; status = wdbDbgHwBpSet (&dbgRegs, access, (UINT32) addr); switch (status) { case WDB_ERR_HW_REGS_EXHAUSTED: printErr (DBG_HW_BKPT_REGS_FULL); return (ERROR); case WDB_ERR_INVALID_HW_BP: printErr (DBG_INV_HW_BKPT_TYPE); return (ERROR); case OK: break; default: return (ERROR); } /* add breakpoint to breakpoint table */ if ((pBp = dbgBrkAdd (addr, tid, access | BRK_HARDWARE, action, count, NULL, 0)) == NULL) { printErr (DBG_BKPT_TBL_FULL); return (ERROR); } return (OK); }#endif /* DBG_HARDWARE_BP *//********************************************************************************* bd - delete a breakpoint** This routine deletes a specified breakpoint.** To execute, enter:* .CS* -> bd addr [,task]* .CE* If <task> is omitted or zero, the breakpoint will be removed for all tasks.* If the breakpoint applies to all tasks, removing it for only a single* task will be ineffective. It must be removed for all tasks and then set* for just those tasks desired. Temporary breakpoints inserted by the* routines so() or cret() can also be deleted.** RETURNS* OK, or ERROR if there is no breakpoint at the specified address.** SEE ALSO: b(),* .pG "Target Shell,"* windsh,* .tG "Shell"*/STATUS bd ( INSTR * addr, /* address of breakpoint to delete */ int task /* task for which to delete breakpoint, */ /* 0 = delete for all tasks */ ) { BRKPT * pBp; int tid = 0; dll_t * pDll; dll_t * pDllNext; if (dbgInstall () != OK) return (ERROR); if (task != 0) tid = taskIdFigure (task); /* convert to task id */ if (tid == ERROR) { printErr (DBG_TASK_NOT_FOUND); return (ERROR); } /* search breakpoint table for entry with correct address & task */ taskLock (); /* LOCK PREEMPTION */ for (pDll = dll_head(&bpList); pDll != dll_end(&bpList); pDll = pDllNext) { pDllNext = dll_next(pDll); pBp = BP_BASE(pDll); if (pBp->bp_addr == addr && (pBp->bp_task == tid || tid == ALL) && !(pBp->bp_flags & BP_HOST)) { wdbDbgBpRemove (pBp); taskUnlock (); /* UNLOCK PREEMPTION */ return (OK); } } taskUnlock (); /* UNLOCK PREEMPTION */ /* * print an error message if we have not found the breakpoint to remove */ printErr (DBG_NO_BKPT_AT_ADDR, (int) addr); if (tid == ALL) printErr ("\n"); else printErr (" for task %#x (%s)\n", tid, taskName (tid)); return (ERROR); }/********************************************************************************* bdall - delete all breakpoints** This routine removes all breakpoints.** To execute, enter:* .CS* -> bdall [task]* .CE* If <task> is specified, all breakpoints that apply to that task are* removed. If <task> is omitted, all breakpoints for all tasks are* removed. Temporary breakpoints inserted by so() or cret() are not* deleted; use bd() instead.** RETURNS: OK, always.** SEE ALSO: bd(),* .pG "Target Shell,"* windsh,* .tG "Shell"*/STATUS bdall ( int task /* task for which to delete breakpoints, */ /* 0 = delete for all tasks */ ) { int tid = 0; dll_t * pDll; dll_t * pDllNext; BRKPT * pBp; if (dbgInstall () != OK) return (ERROR); if (task != 0) tid = taskIdFigure (task); /* convert to task id */ if (tid == ERROR) { printErr (DBG_TASK_NOT_FOUND); return (ERROR); } taskLock (); /* LOCK PREEMPTION */ for (pDll = dll_head(&bpList); pDll != dll_end(&bpList); pDll = pDllNext) { pDllNext = dll_next(pDll); pBp = BP_BASE(pDll); /* we can't remove a breakpoint set by a host tool */ if ((pBp->bp_task == tid || tid == ALL) && !(pBp->bp_flags & BP_HOST)) wdbDbgBpRemove (pBp); } taskUnlock (); /* UNLOCK PREEMPTION */ return (OK); }/********************************************************************************* c - continue from a breakpoint** This routine continues the execution of a task that has stopped at a* breakpoint. ** To execute, enter:* .CS* -> c [task [,addr[,addr1]]]* .CE* If <task> is omitted or zero, the last task referenced is assumed.* If <addr> is non-zero, the program counter is changed to <addr>;* if <addr1> is non-zero, the next program counter is changed to <addr1>,* and the task is continued.** CAVEAT* When a task is continued, c() does not distinguish between a suspended* task or a task suspended by the debugger. Therefore, its use should be* restricted to only those tasks being debugged.* * NOTE* The next program counter, <addr1>, is currently supported only by SPARC.** RETURNS:* OK, or ERROR if the specified task does not exist.** SEE ALSO: tr(),* .pG "Target Shell,"* windsh,* .tG "Shell"*/STATUS c ( int task, /* task that should proceed from breakpoint */ INSTR * addr, /* address to continue at; 0 = next instruction */ INSTR * addr1 /* address for npc; 0 = instruction next to pc */ ) { int tid = 0; WIND_TCB * pTcb; if (dbgInstall () != OK) return (ERROR); if ((tid = taskIdFigure (task)) == ERROR) /* convert to task id */ { printErr (DBG_TASK_NOT_FOUND); return (ERROR); } tid = taskIdDefault (tid); /* set default task id */ if (dbgCheckBreakable (tid) == ERROR) return (ERROR); pTcb = taskTcb(tid); if (pTcb == NULL) return (ERROR); if (!taskIsSuspended (tid)) return (ERROR); /* adjust pc & continue the task */ if (addr != 0) _dbgTaskPCSet (tid, addr, addr1); if (dbgTaskCont (tid) != OK) { printErr (DBG_TASK_IX_NOT_FOUND, tid); return (ERROR); } return (OK); }/********************************************************************************* cret - continue until the current subroutine returns** This routine places a breakpoint at the return address of the current* subroutine of a specified task, then continues execution of that task.** To execute, enter:* .CS* -> cret [task]* .CE* If <task> is omitted or zero, the last task referenced is assumed.** When the breakpoint is hit, information about the task will be printed in* the same format as in single-stepping. The breakpoint is automatically* removed when hit, or if the task hits another breakpoint first.*
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -