trace_syscalls.c 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. #include <linux/ftrace.h>
  2. #include <linux/kernel.h>
  3. #include <asm/syscall.h>
  4. #include "trace_output.h"
  5. #include "trace.h"
  6. static atomic_t refcount;
  7. void start_ftrace_syscalls(void)
  8. {
  9. unsigned long flags;
  10. struct task_struct *g, *t;
  11. if (atomic_inc_return(&refcount) != 1)
  12. goto out;
  13. read_lock_irqsave(&tasklist_lock, flags);
  14. do_each_thread(g, t) {
  15. set_tsk_thread_flag(t, TIF_SYSCALL_FTRACE);
  16. } while_each_thread(g, t);
  17. read_unlock_irqrestore(&tasklist_lock, flags);
  18. out:
  19. atomic_dec(&refcount);
  20. }
  21. void stop_ftrace_syscalls(void)
  22. {
  23. unsigned long flags;
  24. struct task_struct *g, *t;
  25. if (atomic_dec_return(&refcount))
  26. goto out;
  27. read_lock_irqsave(&tasklist_lock, flags);
  28. do_each_thread(g, t) {
  29. clear_tsk_thread_flag(t, TIF_SYSCALL_FTRACE);
  30. } while_each_thread(g, t);
  31. read_unlock_irqrestore(&tasklist_lock, flags);
  32. out:
  33. atomic_inc(&refcount);
  34. }
  35. void ftrace_syscall_enter(struct pt_regs *regs)
  36. {
  37. int syscall_nr;
  38. syscall_nr = syscall_get_nr(current, regs);
  39. trace_printk("syscall %d enter\n", syscall_nr);
  40. }
  41. void ftrace_syscall_exit(struct pt_regs *regs)
  42. {
  43. int syscall_nr;
  44. syscall_nr = syscall_get_nr(current, regs);
  45. trace_printk("syscall %d exit\n", syscall_nr);
  46. }
  47. static int init_syscall_tracer(struct trace_array *tr)
  48. {
  49. start_ftrace_syscalls();
  50. return 0;
  51. }
  52. static void reset_syscall_tracer(struct trace_array *tr)
  53. {
  54. stop_ftrace_syscalls();
  55. }
  56. static struct trace_event syscall_enter_event = {
  57. .type = TRACE_SYSCALL_ENTER,
  58. };
  59. static struct trace_event syscall_exit_event = {
  60. .type = TRACE_SYSCALL_EXIT,
  61. };
  62. static struct tracer syscall_tracer __read_mostly = {
  63. .name = "syscall",
  64. .init = init_syscall_tracer,
  65. .reset = reset_syscall_tracer
  66. };
  67. __init int register_ftrace_syscalls(void)
  68. {
  69. int ret;
  70. ret = register_ftrace_event(&syscall_enter_event);
  71. if (!ret) {
  72. printk(KERN_WARNING "event %d failed to register\n",
  73. syscall_enter_event.type);
  74. WARN_ON_ONCE(1);
  75. }
  76. ret = register_ftrace_event(&syscall_exit_event);
  77. if (!ret) {
  78. printk(KERN_WARNING "event %d failed to register\n",
  79. syscall_exit_event.type);
  80. WARN_ON_ONCE(1);
  81. }
  82. return register_tracer(&syscall_tracer);
  83. }
  84. device_initcall(register_ftrace_syscalls);