Using printk in tracepoint causes the system to freeze

147 views Asked by At

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.

0

There are 0 answers