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