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

📄 servtgt.c

📁 RTEMS (Real-Time Executive for Multiprocessor Systems) is a free open source real-time operating sys
💻 C
📖 第 1 页 / 共 2 页
字号:
/* ************************************************************************** * *  Component:	RDB servers *  Module:	servtgt.c * * $Id: servtgt.c,v 1.3 2002/02/01 17:00:01 joel Exp $ * ************************************************************************** */#include <string.h>#include <sys/errno.h>#include <rdbg/rdbg.h>#include <rdbg/servrpc.h>#include <sys/socket.h>#include <assert.h>#ifdef DDEBUG#define	Ptrace	TgtDbgPtrace#else#define Ptrace	TgtRealPtrace#endif/* * TgtBreakRestoreOrig - Restore original instruction at "addr" * just before single-stepping it. */  intTgtBreakRestoreOrig (int pid, void *addr, void *addr2)            /*             * Process identifier              */            /*             * Breakpoint address              */            /*             * Original instruction or bkpt number              */{  int ret;  int l;  l = (long) Ptrace (RPT_PEEKTEXT, pid, addr, 0, NULL); /* assume ok */  ret = ORG_BREAK (l, (UINT32) addr2);  /* reconstruct old instr */  ret = Ptrace (RPT_POKETEXT, pid, addr, ret, NULL);    /* poke back old */  return ret;}/* * *  TgtBreakCancelStep - Restore the breakpoint at "addr" if the single-step *  has failed at the ptrace level. */#define BKPT0(plst)     ((BASE_BREAK*)(plst)->break_list)  voidTgtBreakCancelStep (PID_LIST * plst){  assert (plst->break_list);  assert (BKPT0 (plst)->clr_step);  if (plst->break_list && BKPT0 (plst)->clr_step) {    int idx = BKPT0 (plst)->last_break;    int data;    data = Ptrace (RPT_PEEKTEXT, plst->pid,                   (char *) plst->break_list[idx].ee_loc, 0, NULL);    assert (!IS_BREAK (data));    Ptrace (RPT_POKETEXT, plst->pid,            (char *) plst->break_list[idx].ee_loc,            (int) SET_BREAK (data), NULL);  }}/* * TgtCreateNew - add a new process into the process management lists. */  voidTgtCreateNew (PID pid, int conn, INT32 child, char *name, Boolean spawn){  int idx;  for (idx = 0; idx < pid_list_cnt; idx++)    if (!pid_list[idx].pid)      break;                    /* find empty */  if (idx >= pid_list_cnt) {    /* no empties, add more */    PID_LIST *tmp_pid_list = pid_list;    pid_list_cnt += PID_LIST_INC;    pid_list = (PID_LIST *) Realloc (pid_list,  /* get new or extend */                                     pid_list_cnt * sizeof (PID_LIST));    if (!pid_list) {            /* out of memory */      pid_list_cnt -= PID_LIST_INC;      if (pid_list_cnt) {       /* realloc failed - malloc again */        pid_list = tmp_pid_list;        /*         * above relies on old pointer being valid after failed realloc          */      }      return;                   /* failed */    }    /*     * now clear newly added space      */    memset (pid_list + pid_list_cnt - PID_LIST_INC, 0,            PID_LIST_INC * sizeof (PID_LIST));    idx = pid_list_cnt - PID_LIST_INC;  } else                        /* clear entry we found */    memset (&pid_list[idx], 0, sizeof (PID_LIST));  /*   * now fill in empty entry    */  pid_list[idx].pid = pid;  pid_list[idx].running = 1;    /* we have not called wait yet */  pid_list[idx].primary_conn = (UCHAR) conn;    /* primary owner */  if (conn != -1) {             /* found caller */    pid_list[idx].owners = 1;    PIDMAP_SET (conn, idx);     /* mask in */  }  pid_list[idx].thread = (UINT32) - 1;  /* no thread for now */  pid_list[idx].last_start = LAST_START;    /* handle MiX bug */  pid_list[idx].name = name ? (char *) StrDup (name) : (char *) NULL;}/* * TgtNotifyWaitChange - send event to clients indicating child changed state. */  voidTgtNotifyWaitChange (PID pid, int status, Boolean exclude){  int conn, idx;  idx = FindPidEntry (pid);     /* locate the pid that changed */  if (idx < 0) {    DPRINTF (("TgtNotifyWaitChange: pid %d not in our list\n", (int) pid));    return;                     /* not in our list */  }  pid_list[idx].running = 0;    /* not running */  pid_list[idx].state = status; /* save status of stop/term */  if (!pid_list[idx].owners && !STS_SIGNALLED (status))    TgtDelete (&pid_list[idx], -1, 0);  /* terminated and no owners */  else {                        /* normal cases */    for (conn = 0; conn < conn_list_cnt; conn++) {  /* now find all interested clients */      if (!conn_list[conn].in_use   /* free entry */          || !PIDMAP_TEST (conn, idx))        continue;               /* not using this pid */      if (conn == exclude)        continue;               /* do not do this one */      TspSendWaitChange (conn, BMSG_WAIT, 1, pid, 0, False);    /* notify of change */    }  }}/* *  TgtNotifyAll - send a message to all clients interested in process. */  voidTgtNotifyAll (int pid_idx, BACK_MSG msg, UINT16 spec,              UINT32 context, int exclude, Boolean force){  int conn;  DPRINTF (("TgtNotifyAll: msg %d (%s) for pid_idx=%d (%d,%d)\n",            msg, BmsgNames[msg], pid_idx, exclude, force));  for (conn = 0; conn < conn_list_cnt; conn++)    if (conn_list[conn].in_use  /* not free */        && PIDMAP_TEST (conn, pid_idx)) {      if (conn != exclude)        TspSendWaitChange (conn, msg, spec, pid_list[pid_idx].pid, context,                           force);    }}/* * TgtDelete - mark process as now uncontrolled. * *  Notes: *     - this function removes a process from the process list. *     - the notify argument indicates a message to send if needed. */  voidTgtDelete (PID_LIST * plst, int conn_idx, BACK_MSG notify){  int idx = plst - pid_list, cnt, conn;  /*   * found    */  cnt = pid_list[idx].owners;  if (cnt) {                    /* some connections to break */    for (conn = 0; cnt && conn < conn_list_cnt; conn++)      if (conn_list[conn].in_use    /* not free */          && PIDMAP_TEST (conn, idx)) { /* found one that uses it */        PIDMAP_CLEAR (conn, idx);        if (notify && conn != conn_idx)          TspSendWaitChange (conn, notify, 0, plst->pid, 0, True);        if (!--cnt)          break;      }  }  if (pid_list[idx].name)    Free (pid_list[idx].name);  /* free string name back */  /*   * Free breakpoint list    */  if (pid_list[idx].break_list != NULL) {    Free (pid_list[idx].break_list);  }  pid_list[idx].pid = 0;        /* gone */}/* * TgtKillAndDelete - kill or detach process and remove entry. */  intTgtKillAndDelete (PID_LIST * plst, struct svc_req *rqstp, Boolean term){  ptrace_in pin;                /* used for ptrace call */  ptrace_out *pout;  /*   * Remove breakpoints    */  if (plst->break_alloc > 0) {    pin.pid = plst->pid;    pin.addr.req = RPT_CLRBREAK;    pin.data = 0;               /* clear all */    pin.flags = PTRFLG_NON_OWNER;    pout = RPCGENSRVNAME (ptrace_2_svc) (&pin, rqstp);    if (pout->result < 0) {      DPRINTF (("TgtKillAndDelete: RPT_CLRBREAK failed %d\n", getErrno ()));      return -1;    }  }  if (term) {                   /* kill */    pin.addr.ptrace_addr_data_in_u.address = 0;    pin.data = -1;              /* Don't want notification from slave */    pin.addr.req = RPT_KILL;  } else {                      /* detach */    pin.addr.ptrace_addr_data_in_u.address = 1;    pin.data = 0;    pin.addr.req = RPT_DETACH;  }  pin.pid = plst->pid;  pin.flags = PTRFLG_FREE | PTRFLG_NON_OWNER;  DPRINTF (("TgtKillAndDelete: ptrace_2_svc (%s (%d), %d)\n",            PtraceName (pin.addr.req), pin.addr.req, pin.pid));  pout = RPCGENSRVNAME (ptrace_2_svc) (&pin, rqstp);    /* start it */  if (pout->errNo == ESRCH && plst->pid)    TgtDelete (plst, -1, BMSG_KILLED);  /* only entry remains */  return 0;}/* * TgtDetachCon - detach a connection's ownership of a process. */  voidTgtDetachCon (int conn_idx, int pid_idx, Boolean delete){  if ((unsigned) pid_idx >= pid_list_cnt || !pid_list[pid_idx].pid)    return;                     /* not valid */  if (PIDMAP_TEST (conn_idx, pid_idx)) {    /* if an owner, release control */    PIDMAP_CLEAR (conn_idx, pid_idx);    if (pid_list[pid_idx].owners)      pid_list[pid_idx].owners--;    if (pid_list[pid_idx].primary_conn == conn_idx)      pid_list[pid_idx].primary_conn = NO_PRIMARY;    if (delete        && !pid_list[pid_idx].owners && PROC_TERMINATED (pid_list + pid_idx))      TgtDelete (&pid_list[pid_idx], -1, 0);    /* remove entry */  }}

⌨️ 快捷键说明

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