Subversion Repositories HelenOS

Rev

Rev 2837 | Rev 2850 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. /** @addtogroup sctrace
  2.  * @{
  3.  */
  4. /** @file
  5.  */
  6.  
  7. #include <stdio.h>
  8. #include <unistd.h>
  9. #include <syscall.h>
  10. #include <ipc/ipc.h>
  11. #include <fibril.h>
  12. #include <errno.h>
  13. #include <udebug.h>
  14.  
  15. #include "syscalls.h"
  16. #include "errors.h"
  17. #include "debug_api.h"
  18.  
  19. #define TIDBUF_SIZE 64
  20. unsigned threadid_buf[TIDBUF_SIZE];
  21.  
  22. int phoneid;
  23. int abort_trace;
  24.  
  25. int task_connect(int taskid)
  26. {
  27.     int rc;
  28.  
  29.     printf("ipc_connect_task(%d)...\n", taskid);
  30.     rc = ipc_connect_kbox(taskid);
  31.     printf("-> %d\n", rc);
  32.     phoneid = rc;
  33.     if (rc < 0) return rc;
  34.  
  35.     printf("debug_begin()\n");
  36.     rc = debug_begin(phoneid);
  37.     printf("-> %d\n", rc);
  38.     if (rc < 0) return rc;
  39.  
  40.     return 0;
  41. }
  42.  
  43. int get_thread_list(void)
  44. {
  45.     int rc;
  46.     int tb_copied;
  47.     int tb_needed;
  48.     int i;
  49.  
  50.  
  51.     printf("send IPC_M_DEBUG_THREAD_READ message\n");
  52.     rc = debug_thread_read(phoneid, (unsigned)threadid_buf,
  53.         TIDBUF_SIZE*sizeof(unsigned), &tb_copied, &tb_needed);
  54.     printf("-> %d\n", rc);
  55.     if (rc < 0) return rc;
  56.  
  57.     printf("thread IDs:");
  58.     for (i=0; i<tb_copied / sizeof(unsigned); i++) {
  59.         printf(" %u", threadid_buf[i]);
  60.     }
  61.     printf("\ntotal of %u threads\n", tb_needed/sizeof(unsigned));
  62.  
  63.     return 0;
  64. }
  65.  
  66. void print_sc_retval(int retval, rv_type_t rv_type)
  67. {
  68.     printf (" -> ");
  69.     if (rv_type == RV_INTEGER) {
  70.         printf("%d", retval);
  71.     } else if (rv_type == RV_HASH) {
  72.         printf("0x%08x", retval);
  73.     } else if (rv_type == RV_ERRNO) {
  74.         if (retval >= -15 && retval <= 0) {
  75.             printf("%d %s (%s)", retval,
  76.                 err_desc[retval].name,
  77.                 err_desc[retval].desc);
  78.         } else {
  79.             printf("%d", retval);
  80.         }
  81.     } else if (rv_type == RV_INT_ERRNO) {
  82.         if (retval >= -15 && retval < 0) {
  83.             printf("%d %s (%s)", retval,
  84.                 err_desc[retval].name,
  85.                 err_desc[retval].desc);
  86.         } else {
  87.             printf("%d", retval);
  88.         }
  89.     }
  90.     putchar('\n');
  91. }
  92.  
  93. void print_sc_args(unsigned *sc_args, int n)
  94. {
  95.     int i;
  96.  
  97.     putchar('(');
  98.     if (n > 0) printf("%d", sc_args[0]);
  99.     for (i=1; i<n; i++) {
  100.         printf(", %d", sc_args[i]);
  101.     }
  102.     putchar(')');
  103. }
  104.  
  105. void sc_ipc_call_async_slow(unsigned *sc_args)
  106. {
  107.     unsigned ipc_args[6];
  108.     int rc;
  109.  
  110.     memset(ipc_args, 0, sizeof(ipc_args));
  111.     rc = debug_mem_read(phoneid, ipc_args, sc_args[1], sizeof(ipc_args));
  112.  
  113.     if (rc >= 0) {
  114.         printf("args: (%u, %u, %u, %u, %u, %u)\n",
  115.             ipc_args[0], ipc_args[1], ipc_args[2],
  116.             ipc_args[3], ipc_args[4], ipc_args[5]);
  117.     }
  118. }
  119.  
  120. int keyboard_fibril(void *arg)
  121. {
  122.     (void)arg;
  123.  
  124.     printf("keyboard fibril started\n");
  125.  
  126.     getchar();
  127.     printf("keyboard fibril setting abort_trace\n");
  128.     abort_trace = 1;
  129.     printf("keyboard fibril sending debug_end()\n");
  130.     debug_end(phoneid);
  131.     printf("keyboard fibril hanging up phone\n");
  132.     ipc_hangup(phoneid);
  133.     printf("keyboard fibril exitting\n");
  134.  
  135.     return EOK;
  136. }
  137.  
  138. void trace_loop(void)
  139. {
  140.     int rc;
  141.     unsigned sc_args[6];
  142.     unsigned copied;
  143.     unsigned ev_type;
  144.     unsigned sc_id;
  145.     int sc_rc;
  146.     int rv_type;
  147.     fid_t kb_fid;
  148.  
  149.     abort_trace = 0;
  150.     kb_fid = fibril_create(keyboard_fibril, NULL);
  151.     if (kb_fid == 0) {
  152.         printf("Failed creating keyboard fibril\n");
  153.         return;
  154.     }
  155.     fibril_add_ready(kb_fid);
  156.  
  157.     while (!abort_trace) {
  158.  
  159.         /* Run thread until a syscall is executed */
  160.         rc = debug_go(phoneid, threadid_buf[0],
  161.             &ev_type, &sc_id, &sc_rc);
  162.  
  163.         printf("rc = %d, ev_type=%d\n", rc, ev_type);
  164.         if (ev_type == UDEBUG_EVENT_FINISHED) {
  165.             printf("thread %u debugging finished\n", threadid_buf[0]);
  166.             break;
  167.         }
  168.  
  169.         /* Read syscall arguments */
  170.         if (rc >= 0) {
  171.             rc = debug_args_read(phoneid, threadid_buf[0],
  172.                 sc_args);
  173.         }
  174.  
  175.         /* Print syscall name, id and arguments */
  176.         if (rc >= 0) {
  177.             printf("%s", syscall_desc[sc_id].name);
  178.             print_sc_args(sc_args, syscall_desc[sc_id].n_args);
  179.             rv_type = syscall_desc[sc_id].rv_type;
  180.             print_sc_retval(sc_rc, rv_type);
  181.         }
  182.  
  183.         switch (sc_id) {
  184.         case SYS_IPC_CALL_ASYNC_SLOW:
  185.             sc_ipc_call_async_slow(sc_args);
  186.             break;
  187.         default:
  188.             break;
  189.         }
  190.     }
  191.  
  192.     printf("trace_loop() exiting\n");
  193. }
  194.  
  195.  
  196. void trace_active_task(void)
  197. {
  198.     int taskid;
  199.     int i;
  200.     int rc;
  201.  
  202.     printf("Syscall Tracer\n");
  203.     printf("Press 'c' to connect\n");
  204.     while ((i = getchar()) != 'c')
  205.         putchar(i);
  206.  
  207.     taskid = 13;
  208.     rc = task_connect(taskid);
  209.     if (rc < 0) {
  210.         printf("Failed to connect to task %d\n", taskid);
  211.         return;
  212.     }
  213.  
  214.     printf("Connected to task %d\n", taskid);
  215.  
  216.     rc = get_thread_list();
  217.     if (rc < 0) {
  218.         printf("Failed to get thread list (error %d)\n", rc);
  219.         return;
  220.     }
  221.  
  222.     trace_loop();
  223. /*
  224.     printf("press 'd' to disconnect\n");
  225.     while ((i = getchar()) != 'd')
  226.         putchar(i);
  227.  
  228.     printf("call debug_end()\n");
  229.     debug_end(phoneid);
  230. */
  231.     printf("done\n");
  232.     return;
  233. }
  234.  
  235. int main(void)
  236. {
  237.     while (1) {
  238.         trace_active_task();
  239.     }
  240. }
  241.  
  242. /** @}
  243.  */
  244.