kprobe_event_gen_test.c 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * Test module for in-kernel kprobe event creation and generation.
  4. *
  5. * Copyright (C) 2019 Tom Zanussi <zanussi@kernel.org>
  6. */
  7. #include <linux/module.h>
  8. #include <linux/trace_events.h>
  9. /*
  10. * This module is a simple test of basic functionality for in-kernel
  11. * kprobe/kretprobe event creation. The first test uses
  12. * kprobe_event_gen_cmd_start(), kprobe_event_add_fields() and
  13. * kprobe_event_gen_cmd_end() to create a kprobe event, which is then
  14. * enabled in order to generate trace output. The second creates a
  15. * kretprobe event using kretprobe_event_gen_cmd_start() and
  16. * kretprobe_event_gen_cmd_end(), and is also then enabled.
  17. *
  18. * To test, select CONFIG_KPROBE_EVENT_GEN_TEST and build the module.
  19. * Then:
  20. *
  21. * # insmod kernel/trace/kprobe_event_gen_test.ko
  22. * # cat /sys/kernel/debug/tracing/trace
  23. *
  24. * You should see many instances of the "gen_kprobe_test" and
  25. * "gen_kretprobe_test" events in the trace buffer.
  26. *
  27. * To remove the events, remove the module:
  28. *
  29. * # rmmod kprobe_event_gen_test
  30. *
  31. */
  32. static struct trace_event_file *gen_kprobe_test;
  33. static struct trace_event_file *gen_kretprobe_test;
  34. /*
  35. * Test to make sure we can create a kprobe event, then add more
  36. * fields.
  37. */
  38. static int __init test_gen_kprobe_cmd(void)
  39. {
  40. struct dynevent_cmd cmd;
  41. char *buf;
  42. int ret;
  43. /* Create a buffer to hold the generated command */
  44. buf = kzalloc(MAX_DYNEVENT_CMD_LEN, GFP_KERNEL);
  45. if (!buf)
  46. return -ENOMEM;
  47. /* Before generating the command, initialize the cmd object */
  48. kprobe_event_cmd_init(&cmd, buf, MAX_DYNEVENT_CMD_LEN);
  49. /*
  50. * Define the gen_kprobe_test event with the first 2 kprobe
  51. * fields.
  52. */
  53. ret = kprobe_event_gen_cmd_start(&cmd, "gen_kprobe_test",
  54. "do_sys_open",
  55. "dfd=%ax", "filename=%dx");
  56. if (ret)
  57. goto free;
  58. /* Use kprobe_event_add_fields to add the rest of the fields */
  59. ret = kprobe_event_add_fields(&cmd, "flags=%cx", "mode=+4($stack)");
  60. if (ret)
  61. goto free;
  62. /*
  63. * This actually creates the event.
  64. */
  65. ret = kprobe_event_gen_cmd_end(&cmd);
  66. if (ret)
  67. goto free;
  68. /*
  69. * Now get the gen_kprobe_test event file. We need to prevent
  70. * the instance and event from disappearing from underneath
  71. * us, which trace_get_event_file() does (though in this case
  72. * we're using the top-level instance which never goes away).
  73. */
  74. gen_kprobe_test = trace_get_event_file(NULL, "kprobes",
  75. "gen_kprobe_test");
  76. if (IS_ERR(gen_kprobe_test)) {
  77. ret = PTR_ERR(gen_kprobe_test);
  78. goto delete;
  79. }
  80. /* Enable the event or you won't see anything */
  81. ret = trace_array_set_clr_event(gen_kprobe_test->tr,
  82. "kprobes", "gen_kprobe_test", true);
  83. if (ret) {
  84. trace_put_event_file(gen_kprobe_test);
  85. goto delete;
  86. }
  87. out:
  88. return ret;
  89. delete:
  90. /* We got an error after creating the event, delete it */
  91. ret = kprobe_event_delete("gen_kprobe_test");
  92. free:
  93. kfree(buf);
  94. goto out;
  95. }
  96. /*
  97. * Test to make sure we can create a kretprobe event.
  98. */
  99. static int __init test_gen_kretprobe_cmd(void)
  100. {
  101. struct dynevent_cmd cmd;
  102. char *buf;
  103. int ret;
  104. /* Create a buffer to hold the generated command */
  105. buf = kzalloc(MAX_DYNEVENT_CMD_LEN, GFP_KERNEL);
  106. if (!buf)
  107. return -ENOMEM;
  108. /* Before generating the command, initialize the cmd object */
  109. kprobe_event_cmd_init(&cmd, buf, MAX_DYNEVENT_CMD_LEN);
  110. /*
  111. * Define the kretprobe event.
  112. */
  113. ret = kretprobe_event_gen_cmd_start(&cmd, "gen_kretprobe_test",
  114. "do_sys_open",
  115. "$retval");
  116. if (ret)
  117. goto free;
  118. /*
  119. * This actually creates the event.
  120. */
  121. ret = kretprobe_event_gen_cmd_end(&cmd);
  122. if (ret)
  123. goto free;
  124. /*
  125. * Now get the gen_kretprobe_test event file. We need to
  126. * prevent the instance and event from disappearing from
  127. * underneath us, which trace_get_event_file() does (though in
  128. * this case we're using the top-level instance which never
  129. * goes away).
  130. */
  131. gen_kretprobe_test = trace_get_event_file(NULL, "kprobes",
  132. "gen_kretprobe_test");
  133. if (IS_ERR(gen_kretprobe_test)) {
  134. ret = PTR_ERR(gen_kretprobe_test);
  135. goto delete;
  136. }
  137. /* Enable the event or you won't see anything */
  138. ret = trace_array_set_clr_event(gen_kretprobe_test->tr,
  139. "kprobes", "gen_kretprobe_test", true);
  140. if (ret) {
  141. trace_put_event_file(gen_kretprobe_test);
  142. goto delete;
  143. }
  144. out:
  145. return ret;
  146. delete:
  147. /* We got an error after creating the event, delete it */
  148. ret = kprobe_event_delete("gen_kretprobe_test");
  149. free:
  150. kfree(buf);
  151. goto out;
  152. }
  153. static int __init kprobe_event_gen_test_init(void)
  154. {
  155. int ret;
  156. ret = test_gen_kprobe_cmd();
  157. if (ret)
  158. return ret;
  159. ret = test_gen_kretprobe_cmd();
  160. if (ret) {
  161. WARN_ON(trace_array_set_clr_event(gen_kretprobe_test->tr,
  162. "kprobes",
  163. "gen_kretprobe_test", false));
  164. trace_put_event_file(gen_kretprobe_test);
  165. WARN_ON(kprobe_event_delete("gen_kretprobe_test"));
  166. }
  167. return ret;
  168. }
  169. static void __exit kprobe_event_gen_test_exit(void)
  170. {
  171. /* Disable the event or you can't remove it */
  172. WARN_ON(trace_array_set_clr_event(gen_kprobe_test->tr,
  173. "kprobes",
  174. "gen_kprobe_test", false));
  175. /* Now give the file and instance back */
  176. trace_put_event_file(gen_kprobe_test);
  177. /* Now unregister and free the event */
  178. WARN_ON(kprobe_event_delete("gen_kprobe_test"));
  179. /* Disable the event or you can't remove it */
  180. WARN_ON(trace_array_set_clr_event(gen_kprobe_test->tr,
  181. "kprobes",
  182. "gen_kretprobe_test", false));
  183. /* Now give the file and instance back */
  184. trace_put_event_file(gen_kretprobe_test);
  185. /* Now unregister and free the event */
  186. WARN_ON(kprobe_event_delete("gen_kretprobe_test"));
  187. }
  188. module_init(kprobe_event_gen_test_init)
  189. module_exit(kprobe_event_gen_test_exit)
  190. MODULE_AUTHOR("Tom Zanussi");
  191. MODULE_DESCRIPTION("kprobe event generation test");
  192. MODULE_LICENSE("GPL v2");