I am learning tracepoint related knowledge of Linux, and I wrote a module, as shown below.
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/moduleparam.h>
#include <linux/unistd.h>
#include <linux/sched.h>
#include <linux/tracepoint.h>
#define MAXNUM 600
MODULE_LICENSE("GPL");
static int monitored_pid = 0;
module_param(monitored_pid, int, 0);
MODULE_PARM_DESC(monitored_pid, "The pid of the monitored process.");
void lookup_tps(struct tracepoint *tp, void *priv);
void sys_enter_probe(struct pt_regs *regs, long id);
static struct tracepoint * sys_enter_tp = NULL;
static unsigned monitored_syscalls[MAXNUM];
static int count = 0;
int __init start(void){
int i = 0;
// find sys_enter tracepoint
for_each_kernel_tracepoint(lookup_tps, NULL);
if(sys_enter_tp == NULL){
printk(KERN_INFO "cannot find sys_enter tracepoint.\n");
// let module loading fail
return -1;
}
if(tracepoint_probe_register(sys_enter_tp, sys_enter_probe, NULL) != 0){
printk(KERN_INFO "regist fail.\n");
return -1;
}
for(i=0; i<MAXNUM; i++){
monitored_syscalls[i] = 0;
}
monitored_syscalls[__NR_open] = 1; // I want to monitor open operation
monitored_syscalls[__NR_openat] = 1;
printk(KERN_INFO "Start to monitor process of pid : %d\n", monitored_pid);
return 0;
}
void __exit end(void){
tracepoint_probe_unregister(sys_enter_tp, sys_enter_probe, NULL);
printk(KERN_INFO "End to monitor process of pid : %d\n", monitored_pid);
printk(KERN_INFO "open count : %d\n", count);
}
void lookup_tps(struct tracepoint *tp, void *priv){
if(strcmp(tp->name, "sys_enter") == 0){
sys_enter_tp = tp;
}
}
void sys_enter_probe(struct pt_regs *regs, long id){
if(id>=MAXNUM){
return;
}
if(monitored_syscalls[id] == 0){
return;
}
if(current->pid != monitored_pid){
return;
}
printk(KERN_INFO "1234\n");
count++;
}
module_init(start);
module_exit(end);
When I entered the insmod command on the command line and pressed Enter, the system did not respond. After many experiments, I found that this problem occurs when writing count or using printk in the probe function(sys_enter_probe). I don't know much about the various mechanisms in the kernel, and I hope someone can tell me what rules my code violates and where I can learn these rules.