Rev 3439 | Rev 3444 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
| Rev 3439 | Rev 3442 | ||
|---|---|---|---|
| Line 70... | Line 70... | ||
| 70 | 70 | ||
| 71 | static int task_connect(task_id_t task_id) |
71 | static int task_connect(task_id_t task_id) |
| 72 | { |
72 | { |
| 73 | int rc; |
73 | int rc; |
| 74 | 74 | ||
| 75 | printf("ipc_connect_task(%lld)... ", task_id); |
- | |
| 76 | rc = ipc_connect_kbox(task_id); |
75 | rc = ipc_connect_kbox(task_id); |
| 77 | printf("-> %d\n", rc); |
- | |
| 78 | 76 | ||
| 79 | if (rc == ENOTSUP) { |
77 | if (rc == ENOTSUP) { |
| 80 | printf("You do not have userspace debugging support " |
78 | printf("You do not have userspace debugging support " |
| 81 | "compiled in the kernel.\n"); |
79 | "compiled in the kernel.\n"); |
| 82 | printf("Compile kernel with 'Support for userspace debuggers' " |
80 | printf("Compile kernel with 'Support for userspace debuggers' " |
| 83 | "(CONFIG_UDEBUG) enabled.\n"); |
81 | "(CONFIG_UDEBUG) enabled.\n"); |
| - | 82 | return rc; |
|
| - | 83 | } |
|
| - | 84 | ||
| - | 85 | if (rc < 0) { |
|
| - | 86 | printf("Error connecting\n"); |
|
| - | 87 | printf("ipc_connect_task(%lld) -> %d ", task_id, rc); |
|
| - | 88 | return rc; |
|
| 84 | } |
89 | } |
| 85 | 90 | ||
| 86 | phoneid = rc; |
91 | phoneid = rc; |
| 87 | if (rc < 0) return rc; |
- | |
| 88 | 92 | ||
| 89 | printf("udebug_begin()... "); |
- | |
| 90 | rc = udebug_begin(phoneid); |
93 | rc = udebug_begin(phoneid); |
| - | 94 | if (rc < 0) { |
|
| 91 | printf("-> %d\n", rc); |
95 | printf("udebug_begin() -> %d\n", rc); |
| 92 | if (rc < 0) return rc; |
96 | return rc; |
| - | 97 | } |
|
| 93 | 98 | ||
| 94 | printf("udebug_set_evmask(0x%x)... ", UDEBUG_EM_ALL); |
- | |
| 95 | rc = udebug_set_evmask(phoneid, UDEBUG_EM_ALL); |
99 | rc = udebug_set_evmask(phoneid, UDEBUG_EM_ALL); |
| 96 | printf("-> %d\n", rc); |
100 | if (rc < 0) { |
| - | 101 | printf("udebug_set_evmask(0x%x) -> %d\n ", UDEBUG_EM_ALL, rc); |
|
| 97 | if (rc < 0) return rc; |
102 | return rc; |
| - | 103 | } |
|
| 98 | 104 | ||
| 99 | return 0; |
105 | return 0; |
| 100 | } |
106 | } |
| 101 | 107 | ||
| 102 | static int get_thread_list(void) |
108 | static int get_thread_list(void) |
| Line 104... | Line 110... | ||
| 104 | int rc; |
110 | int rc; |
| 105 | size_t tb_copied; |
111 | size_t tb_copied; |
| 106 | size_t tb_needed; |
112 | size_t tb_needed; |
| 107 | int i; |
113 | int i; |
| 108 | 114 | ||
| 109 | printf("send IPC_M_DEBUG_THREAD_READ message\n"); |
- | |
| 110 | rc = udebug_thread_read(phoneid, thread_hash_buf, |
115 | rc = udebug_thread_read(phoneid, thread_hash_buf, |
| 111 | THBUF_SIZE*sizeof(unsigned), &tb_copied, &tb_needed); |
116 | THBUF_SIZE*sizeof(unsigned), &tb_copied, &tb_needed); |
| - | 117 | if (rc < 0) { |
|
| 112 | printf("-> %d\n", rc); |
118 | printf("udebug_thread_read() -> %d\n", rc); |
| 113 | if (rc < 0) return rc; |
119 | return rc; |
| - | 120 | } |
|
| 114 | 121 | ||
| 115 | n_threads = tb_copied / sizeof(unsigned); |
122 | n_threads = tb_copied / sizeof(unsigned); |
| 116 | 123 | ||
| 117 | printf("thread IDs:"); |
124 | printf("Threads:"); |
| 118 | for (i=0; i<n_threads; i++) { |
125 | for (i = 0; i < n_threads; i++) { |
| 119 | printf(" %u", thread_hash_buf[i]); |
126 | printf(" [%d] (hash 0x%u)", 1+i, thread_hash_buf[i]); |
| 120 | } |
127 | } |
| 121 | printf("\ntotal of %u threads\n", tb_needed/sizeof(unsigned)); |
128 | printf("\ntotal of %u threads\n", tb_needed/sizeof(unsigned)); |
| 122 | 129 | ||
| 123 | return 0; |
130 | return 0; |
| 124 | } |
131 | } |
| Line 332... | Line 339... | ||
| 332 | } |
339 | } |
| 333 | 340 | ||
| 334 | static void event_thread_b(unsigned hash) |
341 | static void event_thread_b(unsigned hash) |
| 335 | { |
342 | { |
| 336 | async_serialize_start(); |
343 | async_serialize_start(); |
| 337 | printf("new thread, hash 0x%x\n", hash); |
344 | printf("New thread, hash 0x%x\n", hash); |
| 338 | async_serialize_end(); |
345 | async_serialize_end(); |
| 339 | 346 | ||
| 340 | thread_trace_start(hash); |
347 | thread_trace_start(hash); |
| 341 | } |
348 | } |
| 342 | 349 | ||
| Line 349... | Line 356... | ||
| 349 | unsigned val0, val1; |
356 | unsigned val0, val1; |
| 350 | 357 | ||
| 351 | thread_hash = (unsigned)thread_hash_arg; |
358 | thread_hash = (unsigned)thread_hash_arg; |
| 352 | thread_id = next_thread_id++; |
359 | thread_id = next_thread_id++; |
| 353 | 360 | ||
| 354 | printf("trace_loop(%d)\n", thread_id); |
361 | printf("Start tracing thread [%d] (hash 0x%x)\n", thread_id, thread_hash); |
| 355 | 362 | ||
| 356 | while (!abort_trace) { |
363 | while (!abort_trace) { |
| 357 | 364 | ||
| 358 | /* Run thread until an event occurs */ |
365 | /* Run thread until an event occurs */ |
| 359 | rc = udebug_go(phoneid, thread_hash, |
366 | rc = udebug_go(phoneid, thread_hash, |
| 360 | &ev_type, &val0, &val1); |
367 | &ev_type, &val0, &val1); |
| 361 | 368 | ||
| 362 | // printf("rc = %d, ev_type=%d\n", rc, ev_type); |
369 | // printf("rc = %d, ev_type=%d\n", rc, ev_type); |
| 363 | if (ev_type == UDEBUG_EVENT_FINISHED) { |
370 | if (ev_type == UDEBUG_EVENT_FINISHED) { |
| 364 | printf("thread %u debugging finished\n", thread_id); |
371 | /* Done tracing this thread */ |
| 365 | break; |
372 | break; |
| 366 | } |
373 | } |
| 367 | 374 | ||
| 368 | if (rc >= 0) { |
375 | if (rc >= 0) { |
| 369 | switch (ev_type) { |
376 | switch (ev_type) { |
| Line 372... | Line 379... | ||
| 372 | break; |
379 | break; |
| 373 | case UDEBUG_EVENT_SYSCALL_E: |
380 | case UDEBUG_EVENT_SYSCALL_E: |
| 374 | event_syscall_e(thread_id, thread_hash, val0, (int)val1); |
381 | event_syscall_e(thread_id, thread_hash, val0, (int)val1); |
| 375 | break; |
382 | break; |
| 376 | case UDEBUG_EVENT_STOP: |
383 | case UDEBUG_EVENT_STOP: |
| 377 | printf("stop event\n"); |
384 | printf("Stop event\n"); |
| 378 | printf("waiting for resume\n"); |
385 | printf("Waiting for resume\n"); |
| 379 | while (paused) { |
386 | while (paused) { |
| 380 | usleep(1000000); |
387 | usleep(1000000); |
| 381 | fibril_yield(); |
388 | fibril_yield(); |
| 382 | printf("."); |
389 | printf("."); |
| 383 | } |
390 | } |
| 384 | printf("resumed\n"); |
391 | printf("Resumed\n"); |
| 385 | break; |
392 | break; |
| 386 | case UDEBUG_EVENT_THREAD_B: |
393 | case UDEBUG_EVENT_THREAD_B: |
| 387 | event_thread_b(val0); |
394 | event_thread_b(val0); |
| 388 | break; |
395 | break; |
| 389 | case UDEBUG_EVENT_THREAD_E: |
396 | case UDEBUG_EVENT_THREAD_E: |
| 390 | printf("thread 0x%x exited\n", val0); |
397 | printf("Thread 0x%x exited\n", val0); |
| 391 | abort_trace = 1; |
398 | abort_trace = 1; |
| 392 | break; |
399 | break; |
| 393 | default: |
400 | default: |
| 394 | printf("unknown event type %d\n", ev_type); |
401 | printf("Unknown event type %d\n", ev_type); |
| 395 | break; |
402 | break; |
| 396 | } |
403 | } |
| 397 | } |
404 | } |
| 398 | 405 | ||
| 399 | } |
406 | } |
| 400 | 407 | ||
| 401 | printf("trace_loop(%d) exiting\n", thread_id); |
408 | printf("Finished tracing thread [%d]\n", thread_id); |
| 402 | return 0; |
409 | return 0; |
| 403 | } |
410 | } |
| 404 | 411 | ||
| 405 | void thread_trace_start(unsigned thread_hash) |
412 | void thread_trace_start(unsigned thread_hash) |
| 406 | { |
413 | { |
| Line 430... | Line 437... | ||
| 430 | } |
437 | } |
| 431 | 438 | ||
| 432 | printf("Connected to task %lld\n", task_id); |
439 | printf("Connected to task %lld\n", task_id); |
| 433 | 440 | ||
| 434 | ipcp_init(); |
441 | ipcp_init(); |
| - | 442 | ||
| - | 443 | /* |
|
| - | 444 | * User apps now typically have console on phone 3. |
|
| - | 445 | * (Phones 1 and 2 are used by the loader). |
|
| - | 446 | */ |
|
| 435 | ipcp_connection_set(1, 0, proto_console); |
447 | ipcp_connection_set(3, 0, proto_console); |
| 436 | 448 | ||
| 437 | rc = get_thread_list(); |
449 | rc = get_thread_list(); |
| 438 | if (rc < 0) { |
450 | if (rc < 0) { |
| 439 | printf("Failed to get thread list (error %d)\n", rc); |
451 | printf("Failed to get thread list (error %d)\n", rc); |
| 440 | return; |
452 | return; |
| Line 457... | Line 469... | ||
| 457 | if (c == 'r') { |
469 | if (c == 'r') { |
| 458 | paused = 0; |
470 | paused = 0; |
| 459 | } |
471 | } |
| 460 | } |
472 | } |
| 461 | 473 | ||
| 462 | printf("terminate debugging session...\n"); |
474 | printf("\nTerminate debugging session...\n"); |
| 463 | abort_trace = 1; |
475 | abort_trace = 1; |
| 464 | udebug_end(phoneid); |
476 | udebug_end(phoneid); |
| 465 | ipc_hangup(phoneid); |
477 | ipc_hangup(phoneid); |
| 466 | 478 | ||
| 467 | ipcp_cleanup(); |
479 | ipcp_cleanup(); |
| 468 | 480 | ||
| 469 | printf("done\n"); |
481 | printf("Done\n"); |
| 470 | return; |
482 | return; |
| 471 | } |
483 | } |
| 472 | 484 | ||
| 473 | static void main_init(void) |
485 | static void main_init(void) |
| 474 | { |
486 | { |
| Line 518... | Line 530... | ||
| 518 | proto_register(SERVICE_CONSOLE, p); |
530 | proto_register(SERVICE_CONSOLE, p); |
| 519 | } |
531 | } |
| 520 | 532 | ||
| 521 | static void print_syntax() |
533 | static void print_syntax() |
| 522 | { |
534 | { |
| 523 | printf("syntax: trace <task_id>\n"); |
535 | printf("Syntax: trace <task_id>\n"); |
| 524 | } |
536 | } |
| 525 | 537 | ||
| 526 | int main(int argc, char *argv[]) |
538 | int main(int argc, char *argv[]) |
| 527 | { |
539 | { |
| 528 | task_id_t task_id; |
540 | task_id_t task_id; |