~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/samples/kprobes/kretprobe_example.c

Version: ~ [ linux-4.14 ] ~ [ linux-4.13.12 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.61 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.97 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.46 ] ~ [ linux-4.0.9 ] ~ [ linux-3.19.8 ] ~ [ linux-3.18.80 ] ~ [ linux-3.17.8 ] ~ [ linux-3.16.50 ] ~ [ linux-3.15.10 ] ~ [ linux-3.14.79 ] ~ [ linux-3.13.11 ] ~ [ linux-3.12.74 ] ~ [ linux-3.11.10 ] ~ [ linux-3.10.108 ] ~ [ linux-3.9.11 ] ~ [ linux-3.8.13 ] ~ [ linux-3.7.10 ] ~ [ linux-3.6.11 ] ~ [ linux-3.5.7 ] ~ [ linux-3.4.113 ] ~ [ linux-3.3.8 ] ~ [ linux-3.2.95 ] ~ [ linux-3.1.10 ] ~ [ linux-3.0.101 ] ~ [ linux-2.6.39.4 ] ~ [ linux-2.6.38.8 ] ~ [ linux-2.6.37.6 ] ~ [ linux-2.6.36.4 ] ~ [ linux-2.6.35.14 ] ~ [ linux-2.6.34.15 ] ~ [ linux-2.6.33.20 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.27.62 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.5 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /*
  2  * kretprobe_example.c
  3  *
  4  * Here's a sample kernel module showing the use of return probes to
  5  * report the return value and total time taken for probed function
  6  * to run.
  7  *
  8  * usage: insmod kretprobe_example.ko func=<func_name>
  9  *
 10  * If no func_name is specified, _do_fork is instrumented
 11  *
 12  * For more information on theory of operation of kretprobes, see
 13  * Documentation/kprobes.txt
 14  *
 15  * Build and insert the kernel module as done in the kprobe example.
 16  * You will see the trace data in /var/log/messages and on the console
 17  * whenever the probed function returns. (Some messages may be suppressed
 18  * if syslogd is configured to eliminate duplicate messages.)
 19  */
 20 
 21 #include <linux/kernel.h>
 22 #include <linux/module.h>
 23 #include <linux/kprobes.h>
 24 #include <linux/ktime.h>
 25 #include <linux/limits.h>
 26 #include <linux/sched.h>
 27 
 28 static char func_name[NAME_MAX] = "_do_fork";
 29 module_param_string(func, func_name, NAME_MAX, S_IRUGO);
 30 MODULE_PARM_DESC(func, "Function to kretprobe; this module will report the"
 31                         " function's execution time");
 32 
 33 /* per-instance private data */
 34 struct my_data {
 35         ktime_t entry_stamp;
 36 };
 37 
 38 /* Here we use the entry_hanlder to timestamp function entry */
 39 static int entry_handler(struct kretprobe_instance *ri, struct pt_regs *regs)
 40 {
 41         struct my_data *data;
 42 
 43         if (!current->mm)
 44                 return 1;       /* Skip kernel threads */
 45 
 46         data = (struct my_data *)ri->data;
 47         data->entry_stamp = ktime_get();
 48         return 0;
 49 }
 50 
 51 /*
 52  * Return-probe handler: Log the return value and duration. Duration may turn
 53  * out to be zero consistently, depending upon the granularity of time
 54  * accounting on the platform.
 55  */
 56 static int ret_handler(struct kretprobe_instance *ri, struct pt_regs *regs)
 57 {
 58         unsigned long retval = regs_return_value(regs);
 59         struct my_data *data = (struct my_data *)ri->data;
 60         s64 delta;
 61         ktime_t now;
 62 
 63         now = ktime_get();
 64         delta = ktime_to_ns(ktime_sub(now, data->entry_stamp));
 65         pr_info("%s returned %lu and took %lld ns to execute\n",
 66                         func_name, retval, (long long)delta);
 67         return 0;
 68 }
 69 
 70 static struct kretprobe my_kretprobe = {
 71         .handler                = ret_handler,
 72         .entry_handler          = entry_handler,
 73         .data_size              = sizeof(struct my_data),
 74         /* Probe up to 20 instances concurrently. */
 75         .maxactive              = 20,
 76 };
 77 
 78 static int __init kretprobe_init(void)
 79 {
 80         int ret;
 81 
 82         my_kretprobe.kp.symbol_name = func_name;
 83         ret = register_kretprobe(&my_kretprobe);
 84         if (ret < 0) {
 85                 pr_err("register_kretprobe failed, returned %d\n", ret);
 86                 return -1;
 87         }
 88         pr_info("Planted return probe at %s: %p\n",
 89                         my_kretprobe.kp.symbol_name, my_kretprobe.kp.addr);
 90         return 0;
 91 }
 92 
 93 static void __exit kretprobe_exit(void)
 94 {
 95         unregister_kretprobe(&my_kretprobe);
 96         pr_info("kretprobe at %p unregistered\n", my_kretprobe.kp.addr);
 97 
 98         /* nmissed > 0 suggests that maxactive was set too low. */
 99         pr_info("Missed probing %d instances of %s\n",
100                 my_kretprobe.nmissed, my_kretprobe.kp.symbol_name);
101 }
102 
103 module_init(kretprobe_init)
104 module_exit(kretprobe_exit)
105 MODULE_LICENSE("GPL");
106 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | Wiki (Japanese) | Wiki (English) | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

osdn.jp