Rev 3429 | Rev 3536 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 3429 | Rev 3472 | ||
---|---|---|---|
Line 36... | Line 36... | ||
36 | #include <stdlib.h> |
36 | #include <stdlib.h> |
37 | #include <unistd.h> |
37 | #include <unistd.h> |
38 | #include <syscall.h> |
38 | #include <syscall.h> |
39 | #include <ipc/ipc.h> |
39 | #include <ipc/ipc.h> |
40 | #include <fibril.h> |
40 | #include <fibril.h> |
- | 41 | #include <loader/loader.h> |
|
41 | #include <errno.h> |
42 | #include <errno.h> |
42 | #include <udebug.h> |
43 | #include <udebug.h> |
43 | #include <async.h> |
44 | #include <async.h> |
44 | #include <string.h> |
45 | #include <string.h> |
45 | 46 | ||
Line 65... | Line 66... | ||
65 | int app_phone; |
66 | int app_phone; |
66 | volatile bool abort_debug; |
67 | volatile bool abort_debug; |
67 | 68 | ||
68 | volatile int paused; |
69 | volatile int paused; |
69 | 70 | ||
- | 71 | static task_id_t task_id; |
|
- | 72 | static loader_t *task_ldr; |
|
- | 73 | ||
- | 74 | static int program_run_fibril(void *arg); |
|
- | 75 | ||
- | 76 | static void program_run(void) |
|
- | 77 | { |
|
- | 78 | fid_t fid; |
|
- | 79 | ||
- | 80 | fid = fibril_create(program_run_fibril, NULL); |
|
- | 81 | if (fid == 0) { |
|
- | 82 | printf("Error creating fibril\n"); |
|
- | 83 | exit(1); |
|
- | 84 | } |
|
- | 85 | ||
- | 86 | fibril_add_ready(fid); |
|
- | 87 | } |
|
- | 88 | ||
- | 89 | static int program_run_fibril(void *arg) |
|
- | 90 | { |
|
- | 91 | int rc; |
|
- | 92 | ||
- | 93 | /* |
|
- | 94 | * This must be done in background as it will block until |
|
- | 95 | * we let the task reply to this call. |
|
- | 96 | */ |
|
- | 97 | rc = loader_run(task_ldr); |
|
- | 98 | if (rc != 0) { |
|
- | 99 | printf("Error running program\n"); |
|
- | 100 | exit(1); |
|
- | 101 | } |
|
- | 102 | ||
- | 103 | free(task_ldr); |
|
- | 104 | task_ldr = NULL; |
|
- | 105 | ||
- | 106 | return 0; |
|
- | 107 | } |
|
- | 108 | ||
- | 109 | static loader_t *preload_task(const char *path, char *const argv[], |
|
- | 110 | task_id_t *task_id) |
|
- | 111 | { |
|
- | 112 | loader_t *ldr; |
|
- | 113 | int rc; |
|
- | 114 | ||
- | 115 | /* Spawn a program loader */ |
|
- | 116 | ldr = loader_spawn(); |
|
- | 117 | if (ldr == NULL) |
|
- | 118 | return 0; |
|
- | 119 | ||
- | 120 | /* Get task ID. */ |
|
- | 121 | rc = loader_get_task_id(ldr, task_id); |
|
- | 122 | if (rc != EOK) |
|
- | 123 | goto error; |
|
- | 124 | ||
- | 125 | /* Send program pathname */ |
|
- | 126 | rc = loader_set_pathname(ldr, path); |
|
- | 127 | if (rc != EOK) |
|
- | 128 | goto error; |
|
- | 129 | ||
- | 130 | /* Send arguments */ |
|
- | 131 | rc = loader_set_args(ldr, argv); |
|
- | 132 | if (rc != EOK) |
|
- | 133 | goto error; |
|
- | 134 | ||
- | 135 | /* Load the program. */ |
|
- | 136 | rc = loader_load_program(ldr); |
|
- | 137 | if (rc != EOK) |
|
- | 138 | goto error; |
|
- | 139 | ||
- | 140 | /* Success */ |
|
- | 141 | return ldr; |
|
- | 142 | ||
- | 143 | /* Error exit */ |
|
- | 144 | error: |
|
- | 145 | loader_abort(ldr); |
|
- | 146 | free(ldr); |
|
- | 147 | return NULL; |
|
- | 148 | } |
|
- | 149 | ||
- | 150 | ||
70 | static void command_split(char *cmd_str) |
151 | static void command_split(char *cmd_str) |
71 | { |
152 | { |
72 | char *p = cmd_str; |
153 | char *p = cmd_str; |
73 | 154 | ||
74 | if (*p == '\0') { |
155 | if (*p == '\0') { |
Line 169... | Line 250... | ||
169 | { |
250 | { |
170 | cons_printf("singlestep hit\n"); |
251 | cons_printf("singlestep hit\n"); |
171 | thread_stop(); |
252 | thread_stop(); |
172 | } |
253 | } |
173 | 254 | ||
174 | static int task_connect(task_id_t task_id) |
255 | static int connect_task(task_id_t task_id) |
175 | { |
256 | { |
176 | int rc; |
257 | int rc; |
177 | unsigned evmask; |
258 | unsigned evmask; |
178 | 259 | ||
179 | cons_printf("ipc_connect_kbox(%;;d)... ", task_id); |
260 | cons_printf("ipc_connect_kbox(%;;d)... ", task_id); |
Line 326... | Line 407... | ||
326 | dt->fid = fid; |
407 | dt->fid = fid; |
327 | 408 | ||
328 | fibril_add_ready(fid); |
409 | fibril_add_ready(fid); |
329 | } |
410 | } |
330 | 411 | ||
331 | static void debug_active_task(task_id_t task_id) |
412 | static void debug_task(task_id_t task_id) |
332 | { |
413 | { |
333 | int taskid; |
- | |
334 | int i; |
414 | int i; |
335 | int rc; |
415 | int rc; |
336 | 416 | ||
337 | thash_t *thash_buffer; |
417 | thash_t *thash_buffer; |
338 | int n_threads; |
418 | int n_threads; |
339 | 419 | ||
340 | cons_printf("Breakpoint Debugger\n"); |
- | |
341 | - | ||
342 | rc = task_connect(task_id); |
- | |
343 | if (rc < 0) { |
- | |
344 | cons_printf("Failed to connect to task %lld\n", task_id); |
- | |
345 | return; |
- | |
346 | } |
- | |
347 | - | ||
348 | cons_printf("Connected to task %lld\n", task_id); |
- | |
349 | - | ||
350 | rc = get_thread_list(&thash_buffer, &n_threads); |
420 | rc = get_thread_list(&thash_buffer, &n_threads); |
351 | if (rc < 0) { |
421 | if (rc < 0) { |
352 | cons_printf("Failed to get thread list\n", rc); |
422 | cons_printf("Failed to get thread list\n", rc); |
353 | return; |
423 | return; |
354 | } |
424 | } |
Line 386... | Line 456... | ||
386 | cwt = NULL; |
456 | cwt = NULL; |
387 | } |
457 | } |
388 | 458 | ||
389 | static void print_syntax() |
459 | static void print_syntax() |
390 | { |
460 | { |
- | 461 | printf("Syntax:\n"); |
|
- | 462 | printf("\tdebug <executable> [<arg1> [...]]\n"); |
|
391 | printf("syntax: debug <task_id>\n"); |
463 | printf("or\tdebug -t <task_id>\n"); |
392 | } |
464 | } |
393 | 465 | ||
394 | int main(int argc, char *argv[]) |
466 | static int parse_args(int argc, char *argv[]) |
395 | { |
467 | { |
396 | task_id_t task_id; |
468 | char *arg; |
397 | char *err_p; |
469 | char *err_p; |
398 | 470 | ||
- | 471 | task_id = 0; |
|
- | 472 | ||
- | 473 | --argc; ++argv; |
|
- | 474 | ||
399 | if (argc != 2) { |
475 | while (argc > 0) { |
- | 476 | arg = *argv; |
|
- | 477 | if (arg[0] == '-') { |
|
- | 478 | if (arg[1] == 't') { |
|
- | 479 | /* Trace an already running task */ |
|
- | 480 | --argc; ++argv; |
|
- | 481 | task_id = strtol(*argv, &err_p, 10); |
|
- | 482 | task_ldr = NULL; |
|
- | 483 | if (*err_p) { |
|
400 | printf("Mising argument\n"); |
484 | printf("Task ID syntax error\n"); |
- | 485 | print_syntax(); |
|
- | 486 | return -1; |
|
- | 487 | } |
|
- | 488 | } else { |
|
- | 489 | printf("Uknown option '%s'\n", arg[0]); |
|
401 | print_syntax(); |
490 | print_syntax(); |
402 | return 1; |
491 | return -1; |
- | 492 | } |
|
- | 493 | } else { |
|
- | 494 | break; |
|
- | 495 | } |
|
- | 496 | ||
- | 497 | --argc; ++argv; |
|
403 | } |
498 | } |
404 | 499 | ||
- | 500 | if (task_id != 0) { |
|
- | 501 | if (argc == 0) return 0; |
|
405 | task_id = strtol(argv[1], &err_p, 10); |
502 | printf("Extra arguments\n"); |
- | 503 | print_syntax(); |
|
- | 504 | return -1; |
|
- | 505 | } |
|
406 | 506 | ||
407 | if (*err_p) { |
507 | if (argc < 1) { |
408 | printf("Task ID syntax error\n"); |
508 | printf("Missing argument\n"); |
409 | print_syntax(); |
509 | print_syntax(); |
410 | return 1; |
510 | return -1; |
411 | } |
511 | } |
412 | 512 | ||
- | 513 | /* Preload the specified program file. */ |
|
- | 514 | printf("Spawning '%s' with arguments:\n", *argv); |
|
- | 515 | { |
|
- | 516 | char **cp = argv; |
|
- | 517 | while (*cp) printf("'%s'\n", *cp++); |
|
- | 518 | } |
|
- | 519 | task_ldr = preload_task(*argv, argv, &task_id); |
|
- | 520 | ||
- | 521 | return 0; |
|
- | 522 | } |
|
- | 523 | ||
- | 524 | int main(int argc, char *argv[]) |
|
- | 525 | { |
|
- | 526 | int rc; |
|
- | 527 | ||
- | 528 | cons_printf("Breakpoint Debugger\n"); |
|
- | 529 | ||
413 | main_init(); |
530 | main_init(); |
- | 531 | ||
- | 532 | if (parse_args(argc, argv) < 0) |
|
- | 533 | return 1; |
|
- | 534 | ||
- | 535 | rc = connect_task(task_id); |
|
- | 536 | if (rc < 0) { |
|
- | 537 | printf("Failed connecting to task %lld\n", task_id); |
|
- | 538 | return 1; |
|
- | 539 | } |
|
- | 540 | ||
- | 541 | cons_printf("Connected to task %lld\n", task_id); |
|
- | 542 | ||
- | 543 | if (task_ldr != NULL) { |
|
- | 544 | program_run(); |
|
- | 545 | } |
|
- | 546 | ||
414 | debug_active_task(task_id); |
547 | debug_task(task_id); |
- | 548 | ||
- | 549 | return 0; |
|
415 | } |
550 | } |
416 | 551 | ||
417 | /** @} |
552 | /** @} |
418 | */ |
553 | */ |