Subversion Repositories HelenOS

Rev

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