2014-10-19 76 views
0

我想使用模块打印进程ID,进程名称和进程状态,作为测试我尝试使用getpid()函数打印进程ID,但出现以下错误发生:如何使用模块获取进程ID,名称和状态

的功能“printf”式的功能

隐式声明隐式声明“GETPID”

如何解决这些错误,以及如何打印进程名和状态。

#include <linux/init.h> 
#include <linux/module.h> 
#include <linux/kernel.h> 

/* This function is called when the module is loaded. */ 
int simple_init(void) 
{ 
     printk(KERN_INFO "Loading Module\n"); 
     printf("The process id is %\n", (int) getpid()); 
     return 0; 
} 

/* This function is called when the module is removed. */ 
void simple_exit(void) { 
    printk(KERN_INFO "Removing Module\n"); 
} 

/* Macros for registering module entry and exit points. */ 
module_init(simple_init); 
module_exit(simple_exit); 

MODULE_LICENSE("GPL"); 
MODULE_DESCRIPTION("Simple Module"); 
MODULE_AUTHOR("SGG"); 
+1

如果您对Linux应用程序级编程不够熟悉,为什么需要编写内核模块? – 2014-10-19 15:10:51

回答

2

你的问题没有意义。 getpid(以及其他所有syscalls(2) ...)只能在用户应用程序代码中运行,而不能在内核中运行。即使没有任何特定的过程,内核也可能运行一些模块代码。特别是,当模块被加载时,模块初始化发生得很早。

我推荐在编码模块之前阅读Advanced Linux ProgrammingLinux kernel wikipage和kernelnewbies。坏的内核模块可能会丢失所有的数据或者(如果不幸)破坏你的硬件。

您可能想要从内核的调度程序中查询当前任务。请参阅this,但在理解更多内容之前不要编写任何与内核相关的代码。

1

要以非常基本的方式回答您的问题:某些内核的功能(包括init()exit())“代表”用户空间进程执行。也就是说,当您使用insmod插入模块时,将执行init()函数,并且在使用rmmod删除模块时,会执行exit()函数。因此,我们可以说init()函数正在代表insmod进程执行。 exit()rmmod的情况也是如此。

现在,问题是找到该特定函数的相对过程。这可以简单地通过使用宏观current来实现。宏是struct task_struct。需要注意的是,在Linux内部,每个进程的任务控制块(或PCB)由struct task_struct表示。这个数据结构包含了与进程相对应的所有信息,比如状态,名称,MM信息等。我建议您一次查看数据结构。 http://lxr.free-electrons.com/source/include/linux/sched.h#L1223

当一个特定的功能代表过程的执行(比如init()),内核关联的current宏与进程的task_struct。因此,通过简单地访问struct task_struct的各个字段,我们可以获得与该函数相关的过程的信息。

所以,你的情况,也可能是这样的:

current->comm:给人的过程

current->pid名称:给人的过程

希望这有助于的PID。

1
#include <linux/init.h> 
#include <linux/module.h> 
#include <linux/kernel.h> 
#include <linux/sched.h> //task_pid_nr 

/* This function is called when the module is loaded. */ 
int simple_init(void) 
{ 
     printk(KERN_INFO "Loading Module\n"); 
     printk("The process id is %d\n", (int) task_pid_nr(current)); 
     printk("The process vid is %d\n", (int) task_pid_vnr(current)); 
     printk("The process name is %s\n", current->comm); 
     printk("The process tty is %d\n", current->signal->tty); 
     printk("The process group is %d\n", (int) task_tgid_nr(current)); 
     printk("\n\n"); 
    //return -1; //debug mode of working 
    return 0; 
} 

/* This function is called when the module is removed. */ 
void simple_exit(void) { 
    printk(KERN_INFO "Removing Module\n"); 
} 

/* Macros for registering module entry and exit points. */ 
module_init(simple_init); 
module_exit(simple_exit); 

MODULE_LICENSE("GPL"); 
MODULE_DESCRIPTION("Simple Module"); 
MODULE_AUTHOR("SGG");