Subversion Repositories HelenOS

Rev

Rev 2835 | 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 <udebug.h>
  12.  
  13. #include "syscalls.h"
  14. #include "errors.h"
  15. #include "debug_api.h"
  16.  
  17. #define TIDBUF_SIZE 64
  18. unsigned threadid_buf[TIDBUF_SIZE];
  19.  
  20. int phoneid;
  21.  
  22. int task_connect(int taskid)
  23. {
  24.     int rc;
  25.  
  26.     printf("ipc_connect_task(%d)...\n", taskid);
  27.     rc = ipc_connect_kbox(taskid);
  28.     printf("-> %d\n", rc);
  29.     phoneid = rc;
  30.     if (rc < 0) return rc;
  31.  
  32.     printf("debug_begin()\n");
  33.     rc = debug_begin(phoneid);
  34.     printf("-> %d\n", rc);
  35.     if (rc < 0) return rc;
  36.  
  37.     return 0;
  38. }
  39.  
  40. int get_thread_list(void)
  41. {
  42.     int rc;
  43.     int tb_copied;
  44.     int tb_needed;
  45.     int i;
  46.  
  47.  
  48.     printf("send IPC_M_DEBUG_THREAD_READ message\n");
  49.     rc = debug_thread_read(phoneid, (unsigned)threadid_buf,
  50.         TIDBUF_SIZE*sizeof(unsigned), &tb_copied, &tb_needed);
  51.     printf("-> %d\n", rc);
  52.     if (rc < 0) return rc;
  53.  
  54.     printf("thread IDs:");
  55.     for (i=0; i<tb_copied / sizeof(unsigned); i++) {
  56.         printf(" %u", threadid_buf[i]);
  57.     }
  58.     printf("\ntotal of %u threads\n", tb_needed/sizeof(unsigned));
  59.  
  60.     return 0;
  61. }
  62.  
  63. void print_sc_retval(int retval, rv_type_t rv_type)
  64. {
  65.     printf (" -> ");
  66.     if (rv_type == RV_INTEGER) {
  67.         printf("%d", retval);
  68.     } else if (rv_type == RV_HASH) {
  69.         printf("0x%08x", retval);
  70.     } else if (rv_type == RV_ERRNO) {
  71.         if (retval >= -15 && retval <= 0) {
  72.             printf("%d %s (%s)", retval,
  73.                 err_desc[retval].name,
  74.                 err_desc[retval].desc);
  75.         } else {
  76.             printf("%d", retval);
  77.         }
  78.     } else if (rv_type == RV_INT_ERRNO) {
  79.         if (retval >= -15 && retval < 0) {
  80.             printf("%d %s (%s)", retval,
  81.                 err_desc[retval].name,
  82.                 err_desc[retval].desc);
  83.         } else {
  84.             printf("%d", retval);
  85.         }
  86.     }
  87.     putchar('\n');
  88. }
  89.  
  90. void print_sc_args(unsigned *sc_args, int n)
  91. {
  92.     int i;
  93.  
  94.     putchar('(');
  95.     if (n > 0) printf("%d", sc_args[0]);
  96.     for (i=1; i<n; i++) {
  97.         printf(", %d", sc_args[i]);
  98.     }
  99.     putchar(')');
  100. }
  101.  
  102. void sc_ipc_call_async_slow(unsigned *sc_args)
  103. {
  104.     unsigned ipc_args[6];
  105.     int rc;
  106.  
  107.     memset(ipc_args, 0, sizeof(ipc_args));
  108.     rc = debug_mem_read(phoneid, ipc_args, sc_args[1], sizeof(ipc_args));
  109.  
  110.     if (rc >= 0) {
  111.         printf("args: (%u, %u, %u, %u, %u, %u)\n",
  112.             ipc_args[0], ipc_args[1], ipc_args[2],
  113.             ipc_args[3], ipc_args[4], ipc_args[5]);
  114.     }
  115. }
  116.  
  117. void trace_loop(void)
  118. {
  119.     int rc;
  120.     unsigned sc_args[6];
  121.     unsigned copied;
  122.     unsigned ev_type;
  123.     unsigned sc_id;
  124.     int sc_rc;
  125.     int rv_type;
  126.  
  127.     while (1) {
  128.         /* Run thread until a syscall is executed */
  129.         rc = debug_go(phoneid, threadid_buf[0],
  130.             &ev_type, &sc_id, &sc_rc);
  131.  
  132.         /* Read syscall arguments */
  133.         if (rc >= 0) {
  134.             rc = debug_args_read(phoneid, threadid_buf[0],
  135.                 sc_args);
  136.         }
  137.  
  138.         /* Print syscall name, id and arguments */
  139.         if (rc >= 0) {
  140.             printf("%s", syscall_desc[sc_id].name);
  141.             print_sc_args(sc_args, syscall_desc[sc_id].n_args);
  142.             rv_type = syscall_desc[sc_id].rv_type;
  143.             print_sc_retval(sc_rc, rv_type);
  144.         }
  145.  
  146.         switch (sc_id) {
  147.         case SYS_IPC_CALL_ASYNC_SLOW:
  148.             sc_ipc_call_async_slow(sc_args);
  149.             break;
  150.         default:
  151.             break;
  152.         }
  153.     }
  154. }
  155.  
  156.  
  157. void trace_active_task(void)
  158. {
  159.     int taskid;
  160.     int i;
  161.     int rc;
  162.  
  163.     printf("Syscall Tracer\n");
  164.     printf("Press 'c' to connect\n");
  165.     while ((i = getchar()) != 'c')
  166.         putchar(i);
  167.  
  168.     taskid = 13;
  169.     rc = task_connect(taskid);
  170.     if (rc < 0) {
  171.         printf("Failed to connect to task %d\n", taskid);
  172.         return;
  173.     }
  174.  
  175.     printf("Connected to task %d\n", taskid);
  176.  
  177.     rc = get_thread_list();
  178.     if (rc < 0) {
  179.         printf("Failed to get thread list (error %d)\n", rc);
  180.         return;
  181.     }
  182.  
  183.     trace_loop();
  184.  
  185.     printf("done\n");
  186.     return;
  187. }
  188.  
  189. int main(void)
  190. {
  191.     trace_active_task();
  192. }
  193.  
  194. /** @}
  195.  */
  196.