如何使用模块获取进程ID,名称和状态

时间:2014-10-19 14:52:01

标签: c linux module linux-device-driver

我想使用模块打印进程ID,进程名称和进程状态,作为测试我尝试使用getpid()函数打印进程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");

3 个答案:

答案 0 :(得分:2)

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

我建议您在编写模块前阅读Advanced Linux ProgrammingLinux kernel wikipage和kernelnewbies。糟糕的内核模块可能会丢失所有数据,或者(如果不走运)会破坏您的硬件。

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

答案 1 :(得分:2)

以非常基本的方式回答您的问题:内核的某些功能(包括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

希望这有帮助。

答案 2 :(得分: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");