在 tracepoint 中使用 printk 会导致系统冻结

问题描述

我正在学习Linux的tracepoint相关知识,写了一个模块,如下图。

#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,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);

当我在命令行输入insmod命令并按回车时,系统没有反应。经过多次实验,发现在probe函数(sys_enter_probe)中写count或者使用printk时都会出现这个问题。我对内核中的各种机制不太了解,希望有人能告诉我我的代码违反了哪些规则,以及在哪里可以学习这些规则。

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)