Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/samples/kprobes/kprobe_example.c
26282 views
1
// SPDX-License-Identifier: GPL-2.0-only
2
/*
3
* Here's a sample kernel module showing the use of kprobes to dump a
4
* stack trace and selected registers when kernel_clone() is called.
5
*
6
* For more information on theory of operation of kprobes, see
7
* Documentation/trace/kprobes.rst
8
*
9
* You will see the trace data in /var/log/messages and on the console
10
* whenever kernel_clone() is invoked to create a new process.
11
*/
12
13
#define pr_fmt(fmt) "%s: " fmt, __func__
14
15
#include <linux/kernel.h>
16
#include <linux/module.h>
17
#include <linux/kprobes.h>
18
19
static char symbol[KSYM_NAME_LEN] = "kernel_clone";
20
module_param_string(symbol, symbol, KSYM_NAME_LEN, 0644);
21
22
/* For each probe you need to allocate a kprobe structure */
23
static struct kprobe kp = {
24
.symbol_name = symbol,
25
};
26
27
/* kprobe pre_handler: called just before the probed instruction is executed */
28
static int __kprobes handler_pre(struct kprobe *p, struct pt_regs *regs)
29
{
30
#ifdef CONFIG_X86
31
pr_info("<%s> p->addr = 0x%p, ip = %lx, flags = 0x%lx\n",
32
p->symbol_name, p->addr, regs->ip, regs->flags);
33
#endif
34
#ifdef CONFIG_PPC
35
pr_info("<%s> p->addr = 0x%p, nip = 0x%lx, msr = 0x%lx\n",
36
p->symbol_name, p->addr, regs->nip, regs->msr);
37
#endif
38
#ifdef CONFIG_MIPS
39
pr_info("<%s> p->addr = 0x%p, epc = 0x%lx, status = 0x%lx\n",
40
p->symbol_name, p->addr, regs->cp0_epc, regs->cp0_status);
41
#endif
42
#ifdef CONFIG_ARM64
43
pr_info("<%s> p->addr = 0x%p, pc = 0x%lx, pstate = 0x%lx\n",
44
p->symbol_name, p->addr, (long)regs->pc, (long)regs->pstate);
45
#endif
46
#ifdef CONFIG_ARM
47
pr_info("<%s> p->addr = 0x%p, pc = 0x%lx, cpsr = 0x%lx\n",
48
p->symbol_name, p->addr, (long)regs->ARM_pc, (long)regs->ARM_cpsr);
49
#endif
50
#ifdef CONFIG_RISCV
51
pr_info("<%s> p->addr = 0x%p, pc = 0x%lx, status = 0x%lx\n",
52
p->symbol_name, p->addr, regs->epc, regs->status);
53
#endif
54
#ifdef CONFIG_S390
55
pr_info("<%s> p->addr, 0x%p, ip = 0x%lx, flags = 0x%lx\n",
56
p->symbol_name, p->addr, regs->psw.addr, regs->flags);
57
#endif
58
#ifdef CONFIG_LOONGARCH
59
pr_info("<%s> p->addr = 0x%p, era = 0x%lx, estat = 0x%lx\n",
60
p->symbol_name, p->addr, regs->csr_era, regs->csr_estat);
61
#endif
62
63
/* A dump_stack() here will give a stack backtrace */
64
return 0;
65
}
66
67
/* kprobe post_handler: called after the probed instruction is executed */
68
static void __kprobes handler_post(struct kprobe *p, struct pt_regs *regs,
69
unsigned long flags)
70
{
71
#ifdef CONFIG_X86
72
pr_info("<%s> p->addr = 0x%p, flags = 0x%lx\n",
73
p->symbol_name, p->addr, regs->flags);
74
#endif
75
#ifdef CONFIG_PPC
76
pr_info("<%s> p->addr = 0x%p, msr = 0x%lx\n",
77
p->symbol_name, p->addr, regs->msr);
78
#endif
79
#ifdef CONFIG_MIPS
80
pr_info("<%s> p->addr = 0x%p, status = 0x%lx\n",
81
p->symbol_name, p->addr, regs->cp0_status);
82
#endif
83
#ifdef CONFIG_ARM64
84
pr_info("<%s> p->addr = 0x%p, pstate = 0x%lx\n",
85
p->symbol_name, p->addr, (long)regs->pstate);
86
#endif
87
#ifdef CONFIG_ARM
88
pr_info("<%s> p->addr = 0x%p, cpsr = 0x%lx\n",
89
p->symbol_name, p->addr, (long)regs->ARM_cpsr);
90
#endif
91
#ifdef CONFIG_RISCV
92
pr_info("<%s> p->addr = 0x%p, status = 0x%lx\n",
93
p->symbol_name, p->addr, regs->status);
94
#endif
95
#ifdef CONFIG_S390
96
pr_info("<%s> p->addr, 0x%p, flags = 0x%lx\n",
97
p->symbol_name, p->addr, regs->flags);
98
#endif
99
#ifdef CONFIG_LOONGARCH
100
pr_info("<%s> p->addr = 0x%p, estat = 0x%lx\n",
101
p->symbol_name, p->addr, regs->csr_estat);
102
#endif
103
}
104
105
static int __init kprobe_init(void)
106
{
107
int ret;
108
kp.pre_handler = handler_pre;
109
kp.post_handler = handler_post;
110
111
ret = register_kprobe(&kp);
112
if (ret < 0) {
113
pr_err("register_kprobe failed, returned %d\n", ret);
114
return ret;
115
}
116
pr_info("Planted kprobe at %p\n", kp.addr);
117
return 0;
118
}
119
120
static void __exit kprobe_exit(void)
121
{
122
unregister_kprobe(&kp);
123
pr_info("kprobe at %p unregistered\n", kp.addr);
124
}
125
126
module_init(kprobe_init)
127
module_exit(kprobe_exit)
128
MODULE_DESCRIPTION("sample kernel module showing the use of kprobes");
129
MODULE_LICENSE("GPL");
130
131