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>
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");