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

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

Version: ~ [ linux-6.11.5 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.58 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.114 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.169 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.228 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.284 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.322 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

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

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

kernel.org | git.kernel.org | LWN.net | Project Home | 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.

sflogo.php