error: passing argument 4 of ‘proc_create’ from incompatible pointer type [-Werror=incompatible-pointer-types]
今天又在下午做实验(坐牢)期间遇到了折磨人的bug,写完了编译出现一个warning:error: passing argument 4 of ‘proc_create’ from incompatible pointer type [-Werror=incompatible-pointer-types]
在找遍了中文网站都没找到答案后终于受不了了才选择英文网站寻找答案。
error的提示意思是参数指针类型不匹配(pointer incompatible )。本来觉得不匹配也就是一个warning没关系,不过后来还是想找到为什么。。。问题的关键就是老师给出的实验代码太老了,没法在大概linux-2.6.xx后使用了,因此出现了报错。正确答案如下:
把tasklist.c文件第78行左右的函数static struct proc_ops my_proc及其内容替换为如下代码即可:
static struct seq_operations my_seq_fops = {//序列文件记录操作函数集合
.start = my_seq_start,
.next = my_seq_next,
.stop = my_seq_stop,
.show = my_seq_show
};
顺便贴一下tasklist.c的完整代码,有需要的自取:
//-------------------------------------------------------------------
// tasklist.c: 本内核文件创建一个proc伪文件,'/proc/tasklist'
// 通过如下命令可以显示系统中所有进程的部分信息
// 注意:Mkefile文件必须正确放置在当前目录下。
// 编译命令: make
// 内核模块添加:$sudo insmod tasklist.ko
// 添加内核模块后读取并信息tasklist内核信息: $ cat /proc/tasklist
// 内核模块删除:$sudo rmmod tasklist
// NOTE: Written and tested with Linux kernel version 3.13.0 and.3.2.0
// 用户也可以自己完成相关的读写程序,就像课后练习1要求的。我们尤其鼓励同学自己写程序代替cat程序。
// strace函数可用于追踪系统调用,命令格式如下所示:
// $ strace cat /proc/tasklist
//-------------------------------------------------------------------
#include <linux/module.h> // for init_module()
#include <linux/proc_fs.h> // for create_proc_info_entry()
#include <linux/sched.h> // for init_task
#include <linux/seq_file.h> // for sequence files
#include <linux/slab.h> // for kzalloc, kfree
char modname[] = "tasklist";
struct task_struct *task;
int taskcounts=0; // 'global' so value will be retained
static void * my_seq_start(struct seq_file *m, loff_t *pos)
{
///printk(KERN_INFO"Invoke start\n"); //可以输出调试信息
if ( *pos == 0 ) // 表示遍历开始
{
task = &init_task; //遍历开始的记录地址
return &task; //返回一个非零值表示开始遍历
}
else //遍历过程中
{
if (task == &init_task ) //重新回到初始地址,退出
return NULL;
return (void*)pos ;//否则返回一个非零值
}
}
static int my_seq_show(struct seq_file *m, void *v)
{//获取进程的相关信息
//printk(KERN_INFO"Invoke show\n");
seq_printf( m, "#%-3d ", taskcounts++ );
seq_printf( m, "%5d ", task->pid );
seq_printf( m, "%lu ", task->state );
seq_printf( m, "%-15s ", task->comm );
seq_puts( m, "\n" );
return 0;
}
static void * my_seq_next(struct seq_file *m, void *v, loff_t *pos)
{
//printk(KERN_INFO"Invoke next\n");
(*pos)++;
task= next_task(task); //指向下一个进程
return NULL;
}
static void my_seq_stop(struct seq_file *m, void *v)
{
//printk(KERN_INFO"Invoke stop\n");
// do nothing
}
static struct seq_operations my_seq_fops = {//序列文件记录操作函数集合
.start = my_seq_start,
.next = my_seq_next,
.stop = my_seq_stop,
.show = my_seq_show
};
static int my_open(struct inode *inode, struct file *file)
{
return seq_open(file, &my_seq_fops); //打开序列文件并关联my_seq_fops
}
static struct proc_ops my_proc={
.proc_open = my_open,
.proc_release = single_release,
.proc_read = seq_read,
.proc_lseek = seq_lseek,
};
int __init my_init( void )
{
struct proc_dir_entry* my_proc_entry;
printk( "<1>\nInstalling \'%s\' module\n", modname );
my_proc_entry = proc_create(modname, 0x644, NULL, &my_proc);//生成proc文件
if (NULL == my_proc_entry)
{
return -ENOMEM;
}
return 0; //SUCCESS
}
void __exit my_exit( void )
{
remove_proc_entry( modname, NULL );//删除proc文件
printk( "<1>Removing \'%s\' module\n", modname );
}
module_init(my_init);
module_exit(my_exit);
MODULE_LICENSE("GPL");
Makefile代码如下:
obj-m := tasklist.o
KERNELDIR ?= /lib/modules/$(shell uname -r)/build
PWD:=$(shell pwd)
all:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules
clean:
rm -rf *.o *.ko *.mod.* *.symvers *.order
然后就可以继续快乐的编译啦。
这篇博客讲述了作者在进行实验时遇到的一个Linux内核编程问题,即调用proc_create函数时出现'passing argument 4 of ‘proc_create’ from incompatible pointer type'的警告。作者发现这是由于实验代码过旧,不适用于较新的Linux内核版本。解决方案是更新tasklist.c中相关函数的定义。提供了解决问题的代码片段以及完整的tasklist.c代码和Makefile。文章还附带了参考资料链接。
2548

被折叠的 条评论
为什么被折叠?



