📄 dbglib.c
字号:
* RETURNS:* OK, or ERROR if there is no such task or the breakpoint table is* full.** SEE ALSO: so(),* .pG "Target Shell",* windsh,* .tG "Shell"*/STATUS cret ( int task /* task to continue, 0 = default */ ) {#if (DBG_CRET == TRUE) int tid = 0; /* task ID */ REG_SET regSet; /* task's register set */ WIND_TCB * pTcb; /* pointer on task TCB */ INSTR * retAdrs; /* return address */ 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 */ /* check if task is breakable */ if (dbgCheckBreakable (tid) == ERROR) return (ERROR); if (taskRegsGet (tid, ®Set) != OK) { printErr (DBG_TASK_IX_NOT_FOUND, tid); return (ERROR); } pTcb = taskTcb (tid); if (pTcb == NULL) return (ERROR); if (!taskIsSuspended (tid)) return (ERROR); retAdrs = _dbgRetAdrsGet (®Set); /* add breakpoint to breakpoint table */ if (dbgBrkAdd (retAdrs, tid, BP_SO, WDB_ACTION_STOP | WDB_ACTION_NOTIFY, 0, NULL, 0) == NULL) { printErr (DBG_BKPT_TBL_FULL); return (ERROR); } if (dbgTaskCont (tid) != OK) { printErr (DBG_TASK_IX_NOT_FOUND, tid); return (ERROR); } return (OK);#else /* (DBG_CRET == FALSE) */ printErr (DBG_CRET_NOT_SUPP); return (ERROR);#endif /* (DBG_CRET == TRUE) */ }/********************************************************************************* s - single-step a task** This routine single-steps a task that is stopped at a breakpoint. ** To execute, enter:* .CS* -> s [task[,addr[,addr1]]]* .CE* If <task> is omitted or zero, the last task referenced is assumed.* If <addr> is non-zero, then the program counter is changed to <addr>;* if <addr1> is non-zero, the next program counter is changed to <addr1>,* and the task is stepped.** CAVEAT* When a task is continued, s() 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 debugging package is not installed, the task* cannot be found, or the task is not suspended.** SEE ALSO:* .pG "Target Shell,"* windsh,* .tG "Shell"*/STATUS s ( int taskNameOrId, /* task to step; 0 = use default */ INSTR * addr, /* address to step to; 0 = next instruction */ INSTR * addr1 /* address for npc, 0 = next instruction */ ) { int tid; WIND_TCB * pTcb; if (dbgInstall () != OK) return (ERROR); if ((tid = taskIdFigure (taskNameOrId)) == 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 & resume the task */ if (addr != 0) _dbgTaskPCSet (tid, addr, addr1); /* mark task as single-stepping */ DBG_INFO(tid)->wdbState |= WDB_STEP_TARGET; if (taskResume (tid) != OK) return (ERROR); return (OK); }/********************************************************************************* so - single-step, but step over a subroutine** This routine single-steps a task that is stopped at a breakpoint.* However, if the next instruction is a JSR or BSR, so() breaks at the* instruction following the subroutine call instead.** To execute, enter:* .CS* -> so [task]* .CE* If <task> is omitted or zero, the last task referenced is assumed.** SEE ALSO:* .pG "Target Shell",* windsh,* .tG "Shell"*/STATUS so ( int task /* task to step; 0 = use default */ ) { INSTR * pc; int tid; 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); pc = _dbgTaskPCGet (tid); if (_dbgFuncCallCheck (pc)) /* check if function call instruction */ { /* add breakpoint to breakpoint table */ if (dbgBrkAdd (pc + _dbgInstSizeGet (pc), tid, BP_SO, WDB_ACTION_STOP | WDB_ACTION_NOTIFY, 0, NULL, 0) == NULL) { printErr (DBG_BKPT_TBL_FULL); return (ERROR); } if (dbgTaskCont (tid) == ERROR) { printErr (DBG_TASK_IX_NOT_FOUND, tid); return (ERROR); } } else { /* mark task as single-stepping */ DBG_INFO(tid)->wdbState |= WDB_STEP_TARGET; /* resume the task */ if (taskResume (tid) != OK) { printErr (DBG_TASK_IX_NOT_FOUND, tid); return (ERROR); } } return (OK); }/********************************************************************************* dbgBrkAdd - add a breakpoint to the breakpoint table** RETURNS: * Breakpoint structure address or NULL if we can't add the breakpoint.** NOMANUAL*/LOCAL BRKPT * dbgBrkAdd ( INSTR * addr, /* where to set breakpoint */ int task, /* task for which to set breakboint */ unsigned flags, /* breakpoint flags */ unsigned action, /* breakpoint action */ unsigned count, /* breakpoint count */ FUNCPTR callRtn, /* routine to call */ int callArg /* routine argument */ ) { BRKPT * pBp; /* get a free breakpoint entry */ taskLock (); /* LOCK PREEMPTION */ if (dll_empty (&bpFreeList)) pBp = NULL; else { pBp = BP_BASE(dll_tail (&bpFreeList)); dll_remove (&pBp->bp_chain); } taskUnlock (); /* UNLOCK PREEMPTION */ if (pBp == NULL) { pBp = (BRKPT *) malloc (sizeof (BRKPT)); if (pBp == NULL) return (NULL); } /* initialize breakpoint and add to list */ pBp->bp_flags = flags; pBp->bp_addr = addr; pBp->bp_task = task; pBp->bp_action = action; pBp->bp_count = count; pBp->bp_callRtn = (void (*)()) callRtn; pBp->bp_callArg = callArg; if ((pBp->bp_flags & BRK_HARDWARE) == 0) pBp->bp_instr = *addr; taskLock (); /* LOCK PREEMPTION */ dll_insert(&pBp->bp_chain, &bpList); /* add bp to active list */ taskUnlock (); /* UNLOCK PREEMPTION */ return (pBp); }/********************************************************************************* dbgBrkDisplay - display breakpoints** NOMANUAL*/LOCAL void dbgBrkDisplay (void) { dll_t * pDll; BRKPT * pBp; BOOL nobreaks = TRUE; /* flag that no breakpoints are set */ for (pDll = dll_head(&bpList); pDll != dll_end(&bpList); pDll = dll_next(pDll)) { /* * taskLock() and taskUnlock() are useless because of the use of * printf(). So, one or more breakpoints could be deleted by * another task while we are reading the breakpoint list. * If it happens, we can enter an infinite loop. */ pBp = BP_BASE(pDll); nobreaks = FALSE; dbgBrkPrint (pBp->bp_addr); if (pBp->bp_task == ALL) printf (" Task: %9s Count: %2d", "all", pBp->bp_count); else printf (" Task: %#9x Count: %2d", pBp->bp_task, pBp->bp_count);#if DBG_HARDWARE_BP /* print informations on hardware breakpoints */ _dbgBrkDisplayHard (pBp); #endif /* DBG_HARDWARE_BP */ if (pBp->bp_flags & BP_HOST ) printf (" (tgtsvr)"); else { if (pBp->bp_flags & BP_EVENT) printf (" (event)"); else if (pBp->bp_flags & BP_SO ) printf (" (temporary)"); else if (!(pBp->bp_action & WDB_ACTION_NOTIFY )) printf (" (quiet)"); } printf ("\n"); } if (nobreaks) printErr (DBG_NO_BKPTS); }/********************************************************************************* dbgBrkPrint - print breakpoint address** NOMANUAL*/LOCAL void dbgBrkPrint ( INSTR * addr /* address of breakpoint */ ) { char * label; /* pointer to name from symbol table */ void * actVal; /* actual value of label */ SYMBOL_ID symId; /* symbol identifier */ int displacement; char demangled [DBG_DEMANGLE_PRINT_LEN+1]; char * labelToPrint; printf ("0x%08x: ", (UINT32) addr); /* print breakpoint address */ /* print symbolic address and displacement, if any */ if ((symFindSymbol (sysSymTbl, NULL, (void *)addr, SYM_MASK_NONE, SYM_MASK_NONE, &symId) == OK) && (symNameGet (symId, &label) == OK) && (symValueGet (symId, &actVal) == OK)) { labelToPrint = cplusDemangle (label, demangled, sizeof (demangled)); printf ("%-15s", labelToPrint); if ((displacement = (int)addr - (int)actVal) != 0) printf ("+0x%-4x", displacement); else printf ("%6s", ""); /* no displacement */ } else printf ("%21s", ""); /* no symbolic address */ }/********************************************************************************* dbgCheckBreakable - make sure task is breakable** Prints an error message if task is unbreakable.** RETURNS: OK or ERROR.** NOMANUAL*/LOCAL STATUS dbgCheckBreakable ( int task /* task id */ ) { WIND_TCB * pTcb; /* pointer on task TCB */ if (task == ERROR) return (ERROR); pTcb = taskTcb (task); if (pTcb == NULL) { printErr (DBG_TASK_IX_NOT_FOUND, task); return (ERROR); } if ((pTcb->options & VX_UNBREAKABLE) != 0) { int tid = task == 0 ? taskIdSelf () : task; printErr ("Task %#x (%s) is unbreakable.\n", tid, taskName (tid)); return (ERROR); } return (OK); }/********************************************************************************* dbgTlBreak - print info about a breakpoint ** This routine prints info about a breakpoint we have encountered.** RETURNS : NA** NOMANUAL*/LOCAL void dbgTlBreak ( int task, /* taskId */ INSTR * pc, /* task's pc */ INSTR * addr /* breakpoint's address */ ) { WIND_TCB * pTcb; /* pointer on task TCB */ taskIdDefault (task); pTcb = taskTcb(task); if (pTcb == NULL) return; /* print breakpoint info */ printErr ("\nBreak at "); dbgBrkPrint (addr); /* print the address */ printErr (" Task: %#x (%s)\n", task, taskName (task)); nextToDsm = pc; /* update l's default list-from */ /* * Reset the flag dbgUnbreakableOld. This flag was set to prevent * encontering breakpoints in this routine (even breakpoint with * stop action not defined). */ dbgUnbreakableOld = FALSE; }/********************************************************************************* dbgTlSnglStep - print info about a single-stepping task** NOMANUAL*/LOCAL void dbgTlSnglStep ( int task /* task id */ ) { int pc; WIND_TCB * pTcb; dll_t * pDll; dll_t * pNextDll; BRKPT * pBp; /* get pc of the task */ pc = (int) _dbgTaskPCGet (task); /* remove (if any) temporary breakpoint set by so or cret instruction */ taskLock (); /* LOCK PREEMPTION */ for (pDll = dll_head(&bpList); pDll != dll_end(&bpList); pDll = pNextDll) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -