C 唤醒后内核空指针取消引用\u可中断
我试图应用LDD3书中的一些例子。但是,当我向设备写入时,我的模块崩溃。调用进程被终止,崩溃是由唤醒可中断呼叫引起的。 我正在使用内核5.3.0-42-generic。C 唤醒后内核空指针取消引用\u可中断,c,linux,linux-kernel,linux-device-driver,kernel-module,C,Linux,Linux Kernel,Linux Device Driver,Kernel Module,我试图应用LDD3书中的一些例子。但是,当我向设备写入时,我的模块崩溃。调用进程被终止,崩溃是由唤醒可中断呼叫引起的。 我正在使用内核5.3.0-42-generic。 整个代码: 下面是代码: ssize_t device_write(struct file* fd, const char __user* buf, size_t size, loff_t* offset) { printk(KERN_INFO "MyLinuxModule: device is being wr
整个代码:
下面是代码:
ssize_t device_write(struct file* fd, const char __user* buf, size_t size,
loff_t* offset)
{
printk(KERN_INFO "MyLinuxModule: device is being written to, fd=%X.\n", fd);
struct device_info mydevice = charDevices[MINOR(fd->f_inode->i_rdev)];
if (*offset > DEVICE_BLOCK_SIZE) // reached Max size
{
return 0;
}
int true_len = min(size, DEVICE_BLOCK_SIZE - *offset);
if (mutex_lock_interruptible(&mydevice.my_mutex))
return -ERESTARTSYS;
copy_from_user(mydevice.data, buf, true_len);
mydevice.max_data_avaliable += true_len;
mutex_unlock(&mydevice.my_mutex);
printk(KERN_INFO "MyLinuxModule: my_queue=%X.\n", &mydevice.my_queue);
wake_up_interruptible(&mydevice.my_queue);
*offset += true_len;
return true_len;
}
int setup_cdevice(int index)
{
char* device_message = "Hello from the other side\n";
// initiate the cdev struct
cdev_init(&charDevices[index].chardev, &myfops);
// initiate the data
charDevices[index].data = kmalloc(DEVICE_BLOCK_SIZE, GFP_KERNEL);
memcpy(charDevices[index].data, device_message, strlen(device_message));
// initiate the semaphore & queue
mutex_init(&charDevices[index].my_mutex);
init_waitqueue_head(&charDevices[index].my_queue);
charDevices[index].max_data_avaliable = 0;
int err = cdev_add(&charDevices[index].chardev,
MKDEV(MAJOR(majMin), MINOR(majMin) + index), numOfDevices);
if (err) {
printk(KERN_INFO "MyLinuxModule: cdev_add Error : %X\n", err);
return -1;
}
return 0;
}
您是如何填写我的设备。我的队列的?每个条目都有一个
func
成员,该成员由\uuuu wake\u up\u common()
调用。我打赌这是空的。我建议您发布驱动程序的全部源代码,因为错误似乎存在于您没有向我们展示的代码中。我试图添加全部代码,但stackoveflow editor告诉我,我的帖子主要是代码,我需要更多解释。无论如何,我添加了设置等待队列的函数。您也可以发布一个链接。setup\u cdevice
看起来不错,因为init\u waitqueue\u head
将func
成员初始化为default\u wake\u函数
。但是您不在其他地方向队列添加条目吗?例如,在设备读取功能中,如果没有可用数据,是否将读取任务添加到队列中?我会检查代码。struct device\u info mydevice=…
行创建设备结构的副本。但是,与许多其他同步原语一样,waitqueues不能被复制。但是,您可以通过将行更改为struct device\u info*mydevice=&charDevices[MINOR(fd->f_inode->i_rdev)]来存储指向设备的指针代码>。您是如何填写我的设备。我的队列的?每个条目都有一个func
成员,该成员由\uuuu wake\u up\u common()
调用。我打赌这是空的。我建议您发布驱动程序的全部源代码,因为错误似乎存在于您没有向我们展示的代码中。我试图添加全部代码,但stackoveflow editor告诉我,我的帖子主要是代码,我需要更多解释。无论如何,我添加了设置等待队列的函数。您也可以发布一个链接。setup\u cdevice
看起来不错,因为init\u waitqueue\u head
将func
成员初始化为default\u wake\u函数
。但是您不在其他地方向队列添加条目吗?例如,在设备读取功能中,如果没有可用数据,是否将读取任务添加到队列中?我会检查代码。struct device\u info mydevice=…
行创建设备结构的副本。但是,与许多其他同步原语一样,waitqueues不能被复制。但是,您可以通过将行更改为struct device\u info*mydevice=&charDevices[MINOR(fd->f_inode->i_rdev)]来存储指向设备的指针代码>。
[ 8952.921117] BUG: kernel NULL pointer dereference, address: 0000000000000000
[ 8952.921119] #PF: supervisor instruction fetch in kernel mode
[ 8952.921120] #PF: error_code(0x0010) - not-present page
[ 8952.921121] PGD 0 P4D 0
[ 8952.921123] Oops: 0010 [#7] SMP PTI
[ 8952.921137] CPU: 3 PID: 14892 Comm: main Tainted: G D OE 5.3.0-42-generic #34~18.04.1-Ubuntu