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

📄 servbkpt.c

📁 RTEMS (Real-Time Executive for Multiprocessor Systems) is a free open source real-time operating sys
💻 C
📖 第 1 页 / 共 2 页
字号:
/* ********************************************************************** * *  Component:	RDB servers *  Module:	servbkpt.c * *  Synopsis:	Management of breakpoints * * $Id: servbkpt.c,v 1.3 2002/02/01 17:00:01 joel Exp $ * ********************************************************************** */#include <sys/errno.h>#include <assert.h>#include <rdbg/rdbg.h>#include <rdbg/servrpc.h>/*----- Macros -----*/#define BKPT0(plst)	((BASE_BREAK*)(plst)->break_list)#define BKPT_INCR	5           /* how many bkpt slots alloc at a time */#define BKPT_OVER(plst,idx,addr,size) \    ((plst)->break_list[idx].ee_loc + BREAK_SIZE > (UINT32) (addr) \    &&  (plst)->break_list[idx].ee_loc < (UINT32) (addr) + (size))#define BKPT_SLOTS \	(sizeof ((xdr_break*) 0)->thread_list / \	 sizeof ((xdr_break*) 0)->thread_list [0])    /*     *  BreakAlloc - alloc a breakpoint entry.     *     *  This is a generic routine to insert an entry in the     *  breakpoint list. It returns the number of entry just     *  created. It returns -1 if failed.     */  static intBreakAlloc (PID_LIST * plst, Boolean normal){  int idx, len;  xdr_break *blst;  if (!normal) {                /* want 0 entry */    if (plst->break_list) {      return (0);               /* already there */    }    idx = 1;                    /* force alloc below */  } else {    for (idx = 1; idx < (int) plst->break_alloc; idx++) {      if (plst->break_list[idx].type == BRKT_NONE) {        /*         * got a free one          */        memset (&plst->break_list[idx], 0, sizeof (xdr_break));        return (idx);           /* found one */      }    }  }  /*   * idx is the requested entry    */  if (idx >= (int) plst->break_alloc) { /* need more space */    len = plst->break_alloc + BKPT_INCR;    blst = (xdr_break *) Realloc (plst->break_list, len * sizeof (xdr_break));    if (!blst) {      return (-1);              /* failed, no space */    }    plst->break_alloc = len;    /* got more */    plst->break_list = blst;    /*     * Clear new space      */    memset (blst + len - BKPT_INCR, 0, BKPT_INCR * sizeof (xdr_break));    idx = len - BKPT_INCR;      /* next available */    if (!idx) {      idx = 1;                  /* for normal cases */    }  }  return (normal ? idx : 0);    /* return it */}    /*     *  BreakSet - set a breakpoint in process     *     *  Returns the number or -1/errno.     */#ifdef DDEBUGstatic const char *BreakTypes[] = {  "NONE", "INSTR", "READ", "WRITE",  "ACCESS", "EXEC", "OS_CALL", "OS_SWITCH",  "STEPEMUL"};#define BN_MAX		(sizeof BreakTypes / sizeof BreakTypes[0])#define BREAK_NAME(t)	((unsigned) (t) < BN_MAX ? BreakTypes[t] : "???")#endif  intBreakSet (PID_LIST * plst, int conn_idx, xdr_break * bkpt){  int pid = plst->pid;  int type = bkpt->type;  void *addr = (void *) bkpt->ee_loc;  int idx;  int data;  DPRINTF (("BreakSet: type %d (%s) at 0x%x th %d ee_type %d len %d "            "pass %d curr %d list %d %d %d %d\n", type, BREAK_NAME (type),            (int) addr,            bkpt->thread_spec, bkpt->ee_type, bkpt->length, bkpt->pass_count,            bkpt->curr_pass, bkpt->thread_list[0], bkpt->thread_list[1],            bkpt->thread_list[2], bkpt->thread_list[3]));  idx = BreakAlloc (plst, True);    /* get entry */  if (idx < 0) {                /* no memory */    setErrno (ENOMEM);          /* set for safety */    return -1;                  /* return the error */  }  data = TgtPtrace (RPT_PEEKTEXT, pid, addr, 0, NULL);  /* current */  if (getErrno ()) {    return -1;                  /* failed, return the error */  }  if (IS_BREAK (data)) {        /* There is already a break here */    DPRINTF (("BreakSet: already have soft bkpt at %x\n", addr));    if (type == BRKT_STEPEMUL) {      ++BKPT0 (plst)->pad1;      return 1;                 /* Any non-error value is OK */    }    setErrno (EBUSY);    return -1;  }  TgtPtrace (RPT_POKETEXT, pid, addr, SET_BREAK (data), NULL);  if (getErrno ()) {    return -1;  }  plst->break_list[idx] = *bkpt;  plst->break_list[idx].ee_type = data; /* saved data */  /*   * Inform other owners    */  if (type != BRKT_STEPEMUL) {    TgtNotifyAll (plst - pid_list, BMSG_BREAK, 1 /*added */ , idx,                  conn_idx, False);  } else {    ++BKPT0 (plst)->pad1;  }  /*   * Return the number    */  setErrno (0);                 /* Just in case */  return idx;}  intBreakSetAt (PID_LIST * plst, int conn_idx, unsigned long addr,            break_type type){  xdr_break xb;  memset (&xb, 0, sizeof xb);  xb.type = type;  xb.ee_loc = addr;  return BreakSet (plst, conn_idx, &xb);}/*----- Find a breakpoint by address -----*/  intBreakGetIndex (PID_LIST * plst, void *addr){  int idx;  int data = -1;  if (!plst->break_alloc) {    setErrno (EFAULT);    return -1;  }  for (idx = 1; idx < (int) plst->break_alloc; idx++) {    if ((u_long) addr == plst->break_list[idx].ee_loc) {      data = idx;      break;    }  }  return data;}/*----- Getting information about breakpoint -----*/    /*     *  If data > 0, fill "bkpt" with information about breakpoint     *  and return the number of the next one.     *  If data == 0, return the count of breakpoints.     */  intBreakGet (const PID_LIST * plst, int data, xdr_break * bkpt){  int idx;  if (!data) {                  /* just count them */    for (idx = 1; idx < (int) plst->break_alloc; idx++) {      if (plst->break_list[idx].type != BRKT_NONE) {        data++;      }    }    return data;                /* count */  }  if ((unsigned) data >= plst->break_alloc) {    /*     * out of range      */    setErrno (EFAULT);          /* closest match */    return -1;  }  /*   * get it and say which is next    */  *bkpt = plst->break_list[data];  for (idx = (int) data + 1; idx < (int) plst->break_alloc; idx++) {    if (plst->break_list[idx].type != BRKT_NONE) {      return idx;    }  }  return 0;                     /* otherwise returns 0 for no more */}/*----- Clearing bkpts -----*/    /*     *  BreakClear - clear one (if data != 0) or all breakpoints     *  (if data == 0). Return the number of bkpts cleared.     *  If (data == -1), remove step-emulation breakpoints.     */  intBreakClear (PID_LIST * plst, int conn_idx, int data){  int pid_idx = plst - pid_list;  int idx;  int cleared = 0;  int clearStepEmul = 0;  int terminated = PROC_TERMINATED (plst);  int stepEmulCount = 0;  /*   * break handle in data    */  if (!plst->break_alloc) {     /* there are no breaks */    DPRINTF (("BreakClear: no bkpts defined.\n"));    setErrno (EFAULT);          /* closest match */    return -1;                  /* return error */  }  if (!data) {                  /* clear all */    idx = 1;    data = plst->break_alloc - 1;    /*     * Inform other owners      */    DPRINTF (("BreakClear: clearing all bkpts.\n"));    TgtNotifyAll (pid_idx, BMSG_BREAK, 0 /*clr */ , 0, conn_idx, False);  } else if (data == -1) {      /* clear all step-emul bkpts */    DPRINTF (("BreakClear: removing %d step-emul bkpts\n",              BKPT0 (plst)->pad1));    stepEmulCount = BKPT0 (plst)->pad1;    BKPT0 (plst)->pad1 = 0;    clearStepEmul = 1;    idx = 1;    data = plst->break_alloc - 1;  } else if ((unsigned) data >= plst->break_alloc             || plst->break_list[data].type == BRKT_NONE) {    /*     * out of range      */    DPRINTF (("BreakClear: invalid bkpt %d\n", data));    setErrno (EFAULT);          /* closest match */    return -1;                  /* return error */  } else {    idx = data;    /*     * Inform other owners      */    TgtNotifyAll (pid_idx, BMSG_BREAK, 0 /*clr */ , idx, conn_idx, False);    DPRINTF (("BreakClear: clearing bkpt %d\n", data));  }  for (; idx <= data; idx++) {  /* clear each one */    int type = plst->break_list[idx].type;    if (clearStepEmul && type != BRKT_STEPEMUL)      continue;    if (type == BRKT_INSTR || (clearStepEmul && type == BRKT_STEPEMUL)) {      /*       * just patch back        */      char *addr = (char *) plst->break_list[idx].ee_loc;      int val;      if (BKPT0 (plst)->clr_step && BKPT0 (plst)->last_break == idx) {        BKPT0 (plst)->clr_step = 0; /* not needed */      }      /*       * Neighboring bytes can have breakpoints too...        */      if (!terminated) {        setErrno (0);        val = TgtPtrace (RPT_PEEKTEXT, plst->pid, addr, 0, NULL);

⌨️ 快捷键说明

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