ia64/xen-unstable

changeset 16174:1e27eb0c9f22

[IA64] New features for xenitp

Add auto-repeat feature
(Just press enter to re-execute the last go/sstep/cb/disass command).
Do not flush stdout in the signal handler.
Single step over a breakpoint.
Can quit with domain paused (quit paused)
'disp db' now displays watchpoint.

Signed-off-by: Tristan Gingold <tgingold@free.fr>
author Alex Williamson <alex.williamson@hp.com>
date Sun Oct 21 15:52:25 2007 -0600 (2007-10-21)
parents c1e272707063
children 85613b8c4176
files tools/debugger/xenitp/xenitp.c
line diff
     1.1 --- a/tools/debugger/xenitp/xenitp.c	Sun Oct 21 14:57:13 2007 -0600
     1.2 +++ b/tools/debugger/xenitp/xenitp.c	Sun Oct 21 15:52:25 2007 -0600
     1.3 @@ -687,7 +687,6 @@ static volatile int ctrl_c_hit;
     1.4  
     1.5  void ctrl_c_handler (int sig)
     1.6  {
     1.7 -    fflush (stdout);
     1.8      ctrl_c_hit = 1;
     1.9  }
    1.10  
    1.11 @@ -716,6 +715,7 @@ int wait_domain (int vcpu, vcpu_guest_co
    1.12              break;
    1.13  
    1.14          if (ctrl_c_hit) {
    1.15 +            fflush (stdout);
    1.16              /* Force pause.  */
    1.17              ret = xc_domain_pause (xc_handle, domid);
    1.18              if (ret < 0)
    1.19 @@ -957,48 +957,49 @@ int vcpu_setcontext (int vcpu)
    1.20      return ret;
    1.21  }
    1.22  
    1.23 +enum cmd_status { CMD_ERROR, CMD_OK, CMD_REPEAT, CMD_QUIT };
    1.24 +
    1.25  struct command_desc
    1.26  {
    1.27      const char *name;
    1.28      const char *help;
    1.29 -    int (*cmd)(char *line);
    1.30 +    enum cmd_status (*cmd)(char *line);
    1.31  };
    1.32  
    1.33 -static int
    1.34 +static enum cmd_status
    1.35  cmd_registers (char *line)
    1.36  {
    1.37      print_ctx (cur_ctx);
    1.38 -    return 0;
    1.39 +    return CMD_OK;
    1.40  }
    1.41  
    1.42 -static int
    1.43 +static enum cmd_status
    1.44  cmd_sstep (char *line)
    1.45  {
    1.46 -    if ((cur_ctx->regs.psr & (PSR_SS | PSR_TB)) != PSR_SS) {
    1.47 -        cur_ctx->regs.psr |= PSR_SS;
    1.48 -        cur_ctx->regs.psr &= ~PSR_TB;
    1.49 -        if (vcpu_setcontext (cur_vcpu) < 0)
    1.50 -            return -1;
    1.51 -    }
    1.52 +    /* Set psr.dd and psr.id to skip over current breakpoint.  */
    1.53 +    cur_ctx->regs.psr |= PSR_SS | PSR_DD | PSR_ID;
    1.54 +    cur_ctx->regs.psr &= ~PSR_TB;
    1.55 +    if (vcpu_setcontext (cur_vcpu) < 0)
    1.56 +        return CMD_ERROR;
    1.57  
    1.58      if (wait_domain (cur_vcpu, cur_ctx) < 0) {
    1.59          perror ("wait_domain");
    1.60 -        return -1;
    1.61 +        return CMD_ERROR;
    1.62      }
    1.63  
    1.64      print_ctx (cur_ctx);
    1.65  
    1.66 -    return 0;
    1.67 +    return CMD_REPEAT;
    1.68  }
    1.69  
    1.70 -static int
    1.71 +static enum cmd_status
    1.72  cmd_go (char *line)
    1.73  {
    1.74      unsigned long n = 1;
    1.75  
    1.76      if (*line != 0) {
    1.77          if (parse_expr (&line, &n, 0) < 0)
    1.78 -            return -1;
    1.79 +            return CMD_ERROR;
    1.80      }
    1.81      while (n > 0) {
    1.82          /* Set psr.dd and psr.id to skip over current breakpoint.  */
    1.83 @@ -1006,54 +1007,58 @@ cmd_go (char *line)
    1.84              cur_ctx->regs.psr &= ~(PSR_SS | PSR_TB);
    1.85              cur_ctx->regs.psr |= PSR_DD | PSR_ID;
    1.86              if (vcpu_setcontext (cur_vcpu) < 0)
    1.87 -                return -1;
    1.88 +                return CMD_ERROR;
    1.89          }
    1.90  
    1.91          if (wait_domain (cur_vcpu, cur_ctx) < 0) {
    1.92              perror ("wait_domain");
    1.93 -            return -1;
    1.94 +            return CMD_ERROR;
    1.95          }
    1.96          print_ctx (cur_ctx);
    1.97          n--;
    1.98      }
    1.99  
   1.100 -    return 0;
   1.101 +    return CMD_REPEAT;
   1.102  }
   1.103  
   1.104 -static int
   1.105 +static enum cmd_status
   1.106  cmd_cb (char *line)
   1.107  {
   1.108      if ((cur_ctx->regs.psr & (PSR_SS | PSR_TB)) != PSR_TB) {
   1.109          cur_ctx->regs.psr &= ~PSR_SS;
   1.110          cur_ctx->regs.psr |= PSR_TB;
   1.111          if (vcpu_setcontext (cur_vcpu) < 0)
   1.112 -            return -1;
   1.113 +            return CMD_ERROR;
   1.114      }
   1.115  
   1.116      if (wait_domain (cur_vcpu, cur_ctx) < 0) {
   1.117          perror ("wait_domain");
   1.118 -        return -1;
   1.119 +        return CMD_ERROR;
   1.120      }
   1.121  
   1.122      print_ctx (cur_ctx);
   1.123  
   1.124 -    return 0;
   1.125 +    return CMD_REPEAT;
   1.126  }
   1.127  
   1.128 -static int
   1.129 +static int quit_paused;
   1.130 +
   1.131 +static enum cmd_status
   1.132  cmd_quit (char *line)
   1.133  {
   1.134 -    return -2;
   1.135 +    if (!strcmp (line, "paused"))
   1.136 +        quit_paused = 1;
   1.137 +    return CMD_QUIT;
   1.138  }
   1.139  
   1.140 -static int
   1.141 +static enum cmd_status
   1.142  cmd_echo (char *line)
   1.143  {
   1.144      printf ("%s", line);
   1.145 -    return 0;
   1.146 +    return CMD_OK;
   1.147  }
   1.148  
   1.149 -static int
   1.150 +static enum cmd_status
   1.151  cmd_disassemble (char *args)
   1.152  {
   1.153      static unsigned long addr;
   1.154 @@ -1061,21 +1066,20 @@ cmd_disassemble (char *args)
   1.155  
   1.156      if (*args != 0) {
   1.157          if (parse_expr (&args, &addr, 0) < 0)
   1.158 -            return -1;
   1.159 +            return CMD_ERROR;
   1.160          if (*args != 0) {
   1.161              if (parse_expr (&args, &end_addr, 0) < 0)
   1.162 -                return -1;
   1.163 +                return CMD_ERROR;
   1.164          }
   1.165          else 
   1.166              end_addr = addr + 16;
   1.167      }
   1.168      target_disas (stdout, addr, end_addr - addr);
   1.169      addr = end_addr;
   1.170 -    return 0;
   1.171 -
   1.172 +    return CMD_REPEAT;
   1.173  }
   1.174  
   1.175 -static int
   1.176 +static enum cmd_status
   1.177  cmd_break (char *args)
   1.178  {
   1.179      unsigned long addr;
   1.180 @@ -1087,20 +1091,23 @@ cmd_break (char *args)
   1.181  
   1.182      if (i == 4) {
   1.183          printf ("no availabe break points\n");
   1.184 -        return -1;
   1.185 +        return CMD_ERROR;
   1.186      }
   1.187  
   1.188      if (parse_expr (&args, &addr, 0) < 0)
   1.189 -        return -1;
   1.190 +        return CMD_ERROR;
   1.191  
   1.192      cur_ctx->regs.ibr[2 * i] = addr;
   1.193      cur_ctx->regs.ibr[2 * i + 1] = 0x87fffffffffffff0UL;
   1.194      cur_ctx->regs.psr |= PSR_DB;
   1.195  
   1.196 -    return vcpu_setcontext (cur_vcpu);
   1.197 +    if (vcpu_setcontext (cur_vcpu) < 0)
   1.198 +        return CMD_ERROR;
   1.199 +    else
   1.200 +        return CMD_OK;
   1.201  }
   1.202  
   1.203 -static int
   1.204 +static enum cmd_status
   1.205  cmd_watch (char *args)
   1.206  {
   1.207      unsigned long addr;
   1.208 @@ -1113,29 +1120,36 @@ cmd_watch (char *args)
   1.209  
   1.210      if (i == 4) {
   1.211          printf ("no availabe watch points\n");
   1.212 -        return -1;
   1.213 +        return CMD_ERROR;
   1.214      }
   1.215  
   1.216      if (parse_expr (&args, &addr, 0) < 0)
   1.217 -        return -1;
   1.218 +        return CMD_ERROR;
   1.219  
   1.220 -    if (parse_expr (&args, &mask, 0) < 0)
   1.221 +    if (*args == 0)
   1.222          mask = 3;
   1.223 +    else if (parse_expr (&args, &mask, 0) < 0)
   1.224 +        return CMD_ERROR;
   1.225  
   1.226      cur_ctx->regs.dbr[2 * i] = addr;
   1.227      cur_ctx->regs.dbr[2 * i + 1] = ~((1UL << mask) - 1) | (0xc7UL << 56);
   1.228      cur_ctx->regs.psr |= PSR_DB;
   1.229  
   1.230 -    return vcpu_setcontext (cur_vcpu);
   1.231 +    if (vcpu_setcontext (cur_vcpu) < 0)
   1.232 +        return CMD_ERROR;
   1.233 +    else {
   1.234 +        printf ("Watchpoint %d set\n", i);
   1.235 +        return CMD_OK;
   1.236 +    }
   1.237  }
   1.238  
   1.239 -static int
   1.240 +static enum cmd_status
   1.241  cmd_delete (char *args)
   1.242  {
   1.243      unsigned long num;
   1.244  
   1.245      if (parse_expr (&args, &num, 0) < 0)
   1.246 -        return -1;
   1.247 +        return CMD_ERROR;
   1.248  
   1.249      if (num < 4) {
   1.250          cur_ctx->regs.ibr[2 * num] = 0;
   1.251 @@ -1148,61 +1162,70 @@ cmd_delete (char *args)
   1.252      }
   1.253      else {
   1.254          printf ("breakpoint out of range\n");
   1.255 -        return -1;
   1.256 +        return CMD_ERROR;
   1.257      }
   1.258  
   1.259      cur_ctx->regs.psr |= PSR_DB;
   1.260  
   1.261 -    return vcpu_setcontext (cur_vcpu);   
   1.262 +    if (vcpu_setcontext (cur_vcpu) < 0)
   1.263 +        return CMD_ERROR;
   1.264 +    else
   1.265 +        return CMD_OK;
   1.266  }
   1.267  
   1.268 -static int
   1.269 +static enum cmd_status
   1.270  cmd_disable (char *args)
   1.271  {
   1.272      unsigned long num;
   1.273  
   1.274      if (parse_expr (&args, &num, 0) < 0)
   1.275 -        return -1;
   1.276 +        return CMD_ERROR;
   1.277  
   1.278      if (num >= 4) {
   1.279          printf ("breakpoint out of range\n");
   1.280 -        return -1;
   1.281 +        return CMD_ERROR;
   1.282      }
   1.283  
   1.284      cur_ctx->regs.ibr[2 * num + 1] &= ~(1UL << 63);
   1.285  
   1.286 -    return vcpu_setcontext (cur_vcpu);
   1.287 +    if (vcpu_setcontext (cur_vcpu) < 0)
   1.288 +        return CMD_ERROR;
   1.289 +    else
   1.290 +        return CMD_OK;
   1.291  }
   1.292  
   1.293 -static int
   1.294 +static enum cmd_status
   1.295  cmd_enable (char *args)
   1.296  {
   1.297      unsigned long num;
   1.298  
   1.299      if (parse_expr (&args, &num, 0) < 0)
   1.300 -        return -1;
   1.301 +        return CMD_ERROR;
   1.302  
   1.303      if (num >= 4) {
   1.304          printf ("breakpoint out of range\n");
   1.305 -        return -1;
   1.306 +        return CMD_ERROR;
   1.307      }
   1.308  
   1.309      cur_ctx->regs.ibr[2 * num + 1] |= 1UL << 63;
   1.310  
   1.311 -    return vcpu_setcontext (cur_vcpu);
   1.312 +    if (vcpu_setcontext (cur_vcpu) < 0)
   1.313 +        return CMD_ERROR;
   1.314 +    else
   1.315 +        return CMD_OK;
   1.316  }
   1.317  
   1.318 -static int
   1.319 +static enum cmd_status
   1.320  cmd_print (char *args)
   1.321  {
   1.322      unsigned long addr;
   1.323  
   1.324      if (parse_expr (&args, &addr, 0) < 0)
   1.325 -        return -1;
   1.326 +        return CMD_ERROR;
   1.327  
   1.328      printf ("res: 0x%016lx = %ld\n", addr, addr);
   1.329  
   1.330 -    return 0;
   1.331 +    return CMD_OK;
   1.332  }
   1.333  
   1.334  struct bit_xlat {
   1.335 @@ -1228,11 +1251,16 @@ static const struct bit_xlat debug_flags
   1.336      { XEN_IA64_DEBUG_FORCE_DB, "db" },
   1.337      { XEN_IA64_DEBUG_ON_TR, "tr" },
   1.338      { XEN_IA64_DEBUG_ON_TC, "tc" },
   1.339 -    /* { XEN_IA64_DEBUG_ON_KEYS, "keys" }, */
   1.340 +#if 0
   1.341 +    { XEN_IA64_DEBUG_ON_KEYS, "keys" },
   1.342 +    { XEN_IA64_DEBUG_ON_MOV_TO_CR, "mov_to_cr" },
   1.343 +    { XEN_IA64_DEBUG_ON_VHPT, "vhpt" },
   1.344 +    { XEN_IA64_DEBUG_ON_IOSAPIC, "iosapic" },
   1.345 +#endif
   1.346      { 0, NULL }
   1.347  };
   1.348  
   1.349 -static int
   1.350 +static enum cmd_status
   1.351  cmd_disp (char *arg)
   1.352  {
   1.353      if (strcmp (arg, "br") == 0)
   1.354 @@ -1267,6 +1295,11 @@ cmd_disp (char *arg)
   1.355                  printf ("%d: 0x%016lx %s\n", i, cur_ctx->regs.ibr[2 * i],
   1.356                          (cur_ctx->regs.ibr[2 * i + 1] & (1UL << 63)) ?
   1.357                          "enabled" : "disabled");
   1.358 +        for (i = 0; i < 4; i++)
   1.359 +            if (cur_ctx->regs.dbr[2 * i + 1])
   1.360 +                printf ("%d: 0x%016lx %s\n", i, cur_ctx->regs.dbr[2 * i],
   1.361 +                        (cur_ctx->regs.dbr[2 * i + 1] & (1UL << 63)) ?
   1.362 +                        "enabled" : "disabled");
   1.363      }
   1.364      else if (strcmp (arg, "domain") == 0) {
   1.365          xc_dominfo_t dominfo;
   1.366 @@ -1318,12 +1351,14 @@ cmd_disp (char *arg)
   1.367      }
   1.368      else if (*arg == 0)
   1.369          printf ("choose among br, regs, cr, ar, tr, rr, db\n");
   1.370 -    else
   1.371 +    else {
   1.372          printf ("cannot disp '%s'\n", arg);
   1.373 -    return 0;
   1.374 +        return CMD_ERROR;
   1.375 +    }
   1.376 +    return CMD_OK;
   1.377  }
   1.378  
   1.379 -static int
   1.380 +static enum cmd_status
   1.381  cmd_bev (char *arg)
   1.382  {
   1.383      xen_ia64_debug_op_t debug_op;
   1.384 @@ -1332,7 +1367,7 @@ cmd_bev (char *arg)
   1.385      if (do_ia64_debug_op (xc_handle, XEN_IA64_DEBUG_OP_GET_FLAGS,
   1.386                            domid, &debug_op) < 0) {
   1.387          perror ("get debug flags");
   1.388 -        return 0;
   1.389 +        return CMD_ERROR;
   1.390      }
   1.391      if (arg == NULL || arg[0] == 0) {
   1.392          printf ("debug flags: %08lx:\n", debug_op.flags);
   1.393 @@ -1340,7 +1375,7 @@ cmd_bev (char *arg)
   1.394              printf (" %c%s\n",
   1.395                      (debug_flags[i].bit & debug_op.flags) ? '+' : '-',
   1.396                      debug_flags[i].name);
   1.397 -        return 0;
   1.398 +        return CMD_OK;
   1.399      }
   1.400      else {
   1.401          char *p = strtok ((char *)arg, " ");
   1.402 @@ -1357,7 +1392,7 @@ cmd_bev (char *arg)
   1.403                  }
   1.404              if (flag == 0) {
   1.405                  printf ("unknown event %s\n", p);
   1.406 -                return 0;
   1.407 +                return CMD_ERROR;
   1.408              }
   1.409              if (p[0] == '-')
   1.410                  debug_op.flags &= ~flag;
   1.411 @@ -1369,14 +1404,17 @@ cmd_bev (char *arg)
   1.412          if (do_ia64_debug_op (xc_handle, XEN_IA64_DEBUG_OP_SET_FLAGS,
   1.413                                domid, &debug_op) < 0) {
   1.414              perror ("set debug flags");
   1.415 -            return -1;
   1.416 +            return CMD_ERROR;
   1.417          }
   1.418          /* Disabling force_SS and force_DB requires setting psr.  */
   1.419 -        return vcpu_setcontext (cur_vcpu);
   1.420 +        if (vcpu_setcontext (cur_vcpu) < 0)
   1.421 +            return CMD_ERROR;
   1.422 +        else
   1.423 +            return CMD_OK;
   1.424      }
   1.425  }
   1.426  
   1.427 -static int
   1.428 +static enum cmd_status
   1.429  cmd_set (char *line)
   1.430  {
   1.431      char *reg;
   1.432 @@ -1388,20 +1426,23 @@ cmd_set (char *line)
   1.433      addr = get_reg_addr (reg);
   1.434      if (addr == NULL) {
   1.435          printf ("unknown register %s\n", reg);
   1.436 -        return -1;
   1.437 +        return CMD_ERROR;
   1.438      }
   1.439  
   1.440      if (parse_expr (&line, &val, 0) < 0)
   1.441 -        return -1;
   1.442 +        return CMD_ERROR;
   1.443  
   1.444      *addr = val;
   1.445  
   1.446 -    return vcpu_setcontext (cur_vcpu);
   1.447 +    if (vcpu_setcontext (cur_vcpu) < 0)
   1.448 +        return CMD_ERROR;
   1.449 +    else
   1.450 +        return CMD_OK;
   1.451  }
   1.452  
   1.453  const struct command_desc commands[];
   1.454  
   1.455 -static int
   1.456 +static enum cmd_status
   1.457  cmd_help (char *line)
   1.458  {
   1.459      int i;
   1.460 @@ -1409,7 +1450,7 @@ cmd_help (char *line)
   1.461      for (i = 0; commands[i].name; i++)
   1.462          printf ("%s -- %s\n", commands[i].name, commands[i].help);
   1.463  
   1.464 -    return 0;
   1.465 +    return CMD_OK;
   1.466  }
   1.467  
   1.468  const struct command_desc commands[] = {
   1.469 @@ -1434,17 +1475,28 @@ const struct command_desc commands[] = {
   1.470  };
   1.471  
   1.472  
   1.473 -int do_command (int vcpu, char *line)
   1.474 +enum cmd_status do_command (int vcpu, char *line)
   1.475  {
   1.476      char *cmd;
   1.477      char *args;
   1.478      int i;
   1.479      const struct command_desc *desc;
   1.480 +    static const struct command_desc *last_desc;
   1.481 +    enum cmd_status status;
   1.482      int flag_ambiguous;
   1.483  
   1.484      cur_vcpu = vcpu;
   1.485      cur_ctx = &vcpu_ctx[vcpu];
   1.486  
   1.487 +    /* Handle repeat last-command.  */
   1.488 +    if (*line == 0) {
   1.489 +        if (last_desc != NULL)
   1.490 +            return (*last_desc->cmd)("");
   1.491 +        else
   1.492 +            return CMD_OK;
   1.493 +    }
   1.494 +    last_desc = NULL;
   1.495 +
   1.496      cmd = parse_arg (&line);
   1.497      args = line;
   1.498  
   1.499 @@ -1473,32 +1525,28 @@ int do_command (int vcpu, char *line)
   1.500  
   1.501      if (flag_ambiguous) {
   1.502          printf ("\n");
   1.503 -        return -3;
   1.504 +        return CMD_ERROR;
   1.505      }
   1.506      else if (!desc) {
   1.507          printf ("command not found, try help\n");
   1.508 -        return -3;
   1.509 +        return CMD_ERROR;
   1.510      }
   1.511  
   1.512 -    return (*desc->cmd)(args);
   1.513 +    status = (*desc->cmd)(args);
   1.514 +    if (status == CMD_REPEAT)
   1.515 +        last_desc = desc;
   1.516 +    return status;
   1.517  }
   1.518  
   1.519  void xenitp (int vcpu)
   1.520  {
   1.521      int ret;
   1.522 -    xc_dominfo_t dominfo;
   1.523      struct sigaction sa;
   1.524  
   1.525      cur_ctx = &vcpu_ctx[vcpu];
   1.526  
   1.527      xc_handle = xc_interface_open (); /* for accessing control interface */
   1.528  
   1.529 -    ret = xc_domain_getinfo (xc_handle, domid, 1, &dominfo);
   1.530 -    if (ret < 0) {
   1.531 -        perror ("xc_domain_getinfo");
   1.532 -        exit (-1);
   1.533 -    }
   1.534 -
   1.535      if (xc_domain_setdebugging (xc_handle, domid, 1) != 0)
   1.536          perror ("setdebugging");
   1.537  
   1.538 @@ -1510,8 +1558,6 @@ void xenitp (int vcpu)
   1.539  
   1.540      ret = xc_vcpu_getcontext (xc_handle, domid, vcpu, cur_ctx);
   1.541      if (ret < 0) {
   1.542 -        if (!dominfo.paused)
   1.543 -            xc_domain_unpause (xc_handle, domid);
   1.544          perror ("xc_vcpu_getcontext");
   1.545          exit (-1);
   1.546      }
   1.547 @@ -1535,11 +1581,11 @@ void xenitp (int vcpu)
   1.548              break;
   1.549  
   1.550          len = strlen ((char *)buf);
   1.551 -        if (len > 1 && buf[len - 1] == '\n')
   1.552 +        if (len >= 1 && buf[len - 1] == '\n')
   1.553              buf[len - 1] = 0;
   1.554  
   1.555          ret = do_command (vcpu, buf);
   1.556 -        if (ret == -2)
   1.557 +        if (ret == CMD_QUIT)
   1.558              break;
   1.559      }
   1.560  
   1.561 @@ -1554,7 +1600,7 @@ void xenitp (int vcpu)
   1.562      if (xc_domain_setdebugging (xc_handle, domid, 0) != 0)
   1.563              perror ("setdebugging");
   1.564  
   1.565 -    if (!dominfo.paused) {
   1.566 +    if (!quit_paused) {
   1.567          ret = xc_domain_unpause (xc_handle, domid);
   1.568          if (ret < 0) {
   1.569              perror ("xc_domain_unpause");