Debugging Linux kernel using kretprobes - Getting Function Return Value
Consider the scenario, where you want to find out the return value of a particular kernel function without modifying the kernel, kretprobes is the mechanism to go.
What are kretprobes?
kretprobes allows you to call a user-defined function when the function returns.
Sample Code which will give the return value of fork() system call:
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/kprobes.h>
MODULE_LICENSE("GPL");
static struct kretprobe retprobe;
static int ret_handler(struct kretprobe_instance *ri, struct pt_regs *regs)
{
int retval = regs_return_value(regs);
printk(KERN_INFO "%s returned %d\n", "_do_fork", retval);
return 0;
}
static int test_kretprobe_init(void)
{
int retval = 0;
printk(KERN_INFO"%s: In init\n", __func__);
retprobe.kp.symbol_name = "_do_fork";
retprobe.handler = ret_handler;
retval = register_kretprobe(&retprobe);
if (retval < 0) {
printk(KERN_INFO"register_kretprobe failed, returned:%d\n",
retval);
}
return retval;
}
static void test_kretprobe_exit(void)
{
unregister_kretprobe(&retprobe);
printk(KERN_INFO"%s: In exit\n", __func__);
}
module_init(test_kretprobe_init);
module_exit(test_kretprobe_exit);
Output:
What are kretprobes?
kretprobes allows you to call a user-defined function when the function returns.
Sample Code which will give the return value of fork() system call:
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/kprobes.h>
MODULE_LICENSE("GPL");
static struct kretprobe retprobe;
static int ret_handler(struct kretprobe_instance *ri, struct pt_regs *regs)
{
int retval = regs_return_value(regs);
printk(KERN_INFO "%s returned %d\n", "_do_fork", retval);
return 0;
}
static int test_kretprobe_init(void)
{
int retval = 0;
printk(KERN_INFO"%s: In init\n", __func__);
retprobe.kp.symbol_name = "_do_fork";
retprobe.handler = ret_handler;
retval = register_kretprobe(&retprobe);
if (retval < 0) {
printk(KERN_INFO"register_kretprobe failed, returned:%d\n",
retval);
}
return retval;
}
static void test_kretprobe_exit(void)
{
unregister_kretprobe(&retprobe);
printk(KERN_INFO"%s: In exit\n", __func__);
}
module_init(test_kretprobe_init);
module_exit(test_kretprobe_exit);
Output:
Comments
Post a Comment