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

📄 servtgt.c

📁 RTEMS (Real-Time Executive for Multiprocessor Systems) is a free open source real-time operating sys
💻 C
📖 第 1 页 / 共 2 页
字号:
/* -----------------------------------------------------------------------   TgtHandleChildChange - decide what action to take after wait() returns.		Used in the master only.   ----------------------------------------------------------------------- */#ifdef DDEBUGstatic char *LastStartNames[] = {  "NONE", "STEP", "CONT", "RANGE",  "STEPOFF", "KILLED", "DETACHED"};  char *GetLastStartName (int last_start){  static char buf[32];  strcpy (buf, LastStartNames[last_start & ~LAST_START]);  if (last_start & LAST_START) {    strcat (buf, "+START");  }  return buf;}#endif  BooleanTgtHandleChildChange (PID pid, int *status, int *unexp,                      CPU_Exception_frame * ctx){                               /* return False if continue, else stop */  int idx, sig;  int bidx = 0;  PID_LIST *plst;  unsigned long PC;  BASE_BREAK *base = NULL;      /* break_list[0] is really BASE_BREAK */  int hadStepEmul;  int origHadStepEmul;  int stopWanted;  DPRINTF (("TgtHandleChildChange: pid %d status %x cap\n",            (int) pid, *status));  if (unexp)    *unexp = 0;                 /* initialize to ok */  /*   * first, find pid in question    */  idx = FindPidEntry (pid);  if (idx < 0) {                /* cannot locate this process */    DPRINTF (("TgtHandleChildChange: unknown process (%s pid)\n",              FindPidEntry (pid) >= 0 ? "stale" : "unknown"));    if (unexp)      *unexp = 1;               /* Unexpected change */    return (False);             /* unknown: ignore (used to stop and notify) */  }  /*   * found    */  plst = &pid_list[idx];        /* pointer to entry */  /*   * first we see if just stopped    */  /*   * copy ctxt    */  CtxToRegs (ctx, &(plst->regs));  stopWanted = plst->stop_wanted;  plst->stop_wanted = 0;        /* For the next time */  hadStepEmul = BreakClear (plst, -1, -1) > 0;  origHadStepEmul = hadStepEmul;    /* hadStepEmul is cleared if real bkpt met */  if (STS_SIGNALLED (*status)) {    /* stopped, not terminated */    sig = STS_GETSIG (*status); /* signal that stopped us */    /*     * now, we read the registers and see what to do next      */    if (TgtPtrace (RPT_GETREGS, pid, (void *) &plst->regs, 0, NULL) < 0) {      memset (&plst->regs, 0, sizeof (plst->regs));    }    /*     * Get current thread      */    plst->thread = TgtPtrace (RPT_GETTARGETTHREAD, pid, NULL, 0, NULL);    if (sig == SIGTRAP) {       /* stopped from break/step */      PC = plst->regs.REG_PC;      /*       * Must check PC to see whether in situations where we had       * step emulation we are on a breakpoint or just       * have returned from an emulated single-step        */      if (BreakIdentify (plst, 0 /*no adjust */ , -1 /*no thread */ ) > 0) {        hadStepEmul = 0;      }      plst->is_step = hadStepEmul || IS_STEP (plst->regs)        || plst->last_start == LAST_START;      DPRINTF (("TgtHandleChildChange: %s last_start %s\n", plst->is_step                ? "step" : "break", GetLastStartName (plst->last_start)));      if ((plst->is_step || origHadStepEmul || stopWanted)          && (plst->last_start == LAST_STEP              || plst->last_start == LAST_STEPOFF              || plst->last_start == LAST_RANGE)) {        DPRINTF (("TgtHandleChildChange: restoring stepped-off bkpt\n"));        BreakSteppedOff (plst);      }      if (plst->last_start == LAST_STEPOFF && (plst->is_step || origHadStepEmul)) { /* stepped off break and now need cont */        DPRINTF (("TgtHandleChildChange: auto-resuming after step-off\n"));        plst->last_start = LAST_CONT;   /* convert to normal cont */        if (!stopWanted) {          if (TgtPtrace (RPT_CONT, pid, (char *) 1, 0, NULL))            return True;        /* tell people */          return (False);       /* wait for change */        }        DPRINTF (("TgtHandleChildChange: stop_wanted %d in step-off\n",                  stopWanted));        *status = STS_MAKESIG (stopWanted);        return True;            /* Stop and notify */      }      base = plst->break_list ? ((BASE_BREAK *) plst->break_list) :        ((BASE_BREAK *) NULL);      /*       * now see if step in range        */      if (plst->last_start == LAST_RANGE    /* step in range */          && (plst->is_step || origHadStepEmul) /* not a breakpoint */          &&PC >= base->range_start && PC <= base->range_end) { /* still in range, keep going */        if (stopWanted) {          DPRINTF (("TgtHandleChildChange: stop_wanted %d in step-range\n",                    stopWanted));        } else {          DPRINTF (("TgtHandleChildChange: Reservation at %x\n",                    plst->regs.REG_PC));        }      }      if (!plst->is_step) {     /* was break */        bidx = BreakIdentify (plst, 1 /*adjust */ , plst->thread);        if (bidx == 0) {          DPRINTF (("TgtHandleChildChange: forwarding bkpt to kernel\n"));          if (unexp) {            *unexp = 1;          }          return False;        }        if (bidx < 0) {         /* Unwanted breakpoint, must step it off */          ptrace_in pin;          ptrace_out *out;          if (origHadStepEmul) {            DPRINTF (("TgtHandleChildChange: bkpt %x becomes step\n",                      plst->regs.REG_PC));            bidx = -bidx;            plst->is_step = 1;            base->clr_step = plst->break_list[bidx].type == BRKT_INSTR;            base->last_break = bidx;            return True;          }          if (stopWanted) {            DPRINTF (("TgtHandleChildChange: stop_wanted %d at bkpt %x\n",                      stopWanted, plst->regs.REG_PC));            /*             * The PC has already been adjusted by BreakIdentify              */            *status = STS_MAKESIG (stopWanted);            return True;          }          /*           * All the handling is done in ptrace_2_svc() so call it            */          bidx = -bidx;          DPRINTF (("TgtHandleChildChange: last %d (%s) restarting bkpt %d\n",                    plst->last_start, GetLastStartName (plst->last_start),                    bidx));          base->clr_step = 1;          base->last_break = bidx;  /* remember which one */          plst->running = 0;    /* So that ptrace is accepted */          pin.pid = plst->pid;          if (plst->last_start == LAST_STEP) {            pin.addr.req = RPT_SINGLESTEP;          } else {            pin.addr.req = RPT_CONT;          }          pin.addr.ptrace_addr_data_in_u.address = 1;          pin.data = 0;          pin.flags = PTRFLG_NON_OWNER;          out = RPCGENSRVNAME (ptrace_2_svc) (&pin, NULL);          if (out->result == 0)            return False;       /* Continue waiting */          DPRINTF (("TgtHandleChildChange: failed to restart bkpt!\n"));          /*           * If something went wrong, just stop on breakpoint            */        }      }    }    /*     * else sig != SIGTRAP      */    /*     * finally, fill in stop info in break point array base      */    if (bidx > 0) {             /* store break info */      /*       * will need to get off the break for SW breakpoints only        */      base->clr_step = plst->break_list[bidx].type == BRKT_INSTR;      base->last_break = bidx;  /* remember which one */    } else if (base) {          /* clear break info */      base->clr_step = False;   /* not stopped on break */      base->last_break = 0;    }    /*     * decision to notify owner based on last_start      */  } /* stopped */  else {                        /* terminated */    if (plst->last_start == LAST_START) {   /* spawn failed */      TgtNotifyAll (idx, BMSG_EXEC_FAIL, 0, 0, -1, True);      plst->running = False;    /* not running - dead */      plst->state = *status;    /* contains errno in high word */      return (False);    }    else if ((UCHAR) (plst->last_start & ~LAST_START) < (UCHAR) LAST_KILLED)      plst->last_start = LAST_NONE; /* doesn't matter anymore */    else      return (False);           /* killed and detach already notified */  }  return (True);                /* stop and notify */}#ifdef DDEBUG/* * TgtDbgPtrace - debug version of ptrace. */  intTgtDbgPtrace (int request, PID pid, char *addr, int data, void *addr2){  int diag;  DPRINTF (("TgtDbgPtrace: entered (%s (%d), %d, %x, %d, %x)\n",            PtraceName (request), request, pid, (int) addr, data,            (int) addr2));  if (request == RPT_WRITETEXT || request == RPT_WRITEDATA) {    int i;    DPRINTF (("TgtDbgPtrace:"));    if (rdb_debug) {      for (i = 0; i < data && i < 16; ++i) {        printf (" %02x", ((char *) addr2)[i] & 0xFF);      }      printf ("\n");    }  }  diag = TgtRealPtrace (request, pid, addr, data, addr2);  DPRINTF (("TgtDbgPtrace: returned %d (%x) errno %d\n",            diag, diag, getErrno ()));  if (request == RPT_GETREGS || request == RPT_GETTHREADREGS      || request == RPT_SETREGS || request == RPT_SETTHREADREGS) {    /*     * Use DPRINTF() so as to have the id prefix      */    DPRINTF (("TgtDbgPtrace: (%s) PC = %x, SP = %x, FP = %x\n",              PtraceName (request),              ((xdr_regs *) addr)->REG_PC,              ((xdr_regs *) addr)->REG_SP, ((xdr_regs *) addr)->REG_FP));  }  return (diag);}#endif /* DDEBUG */

⌨️ 快捷键说明

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