新手上路
- 积分
- 33
- 金钱
- 33
- 注册时间
- 2019-11-11
- 在线时间
- 7 小时
|
在做阻塞I/O实验时,对原子例程代码稍做了一点修改遇到了Segmentation fault 下面上代码:原子例程14 block.c中 208行起 代码片段如下:
DECLARE_WAITQUEUE(wait, current); /* 定义一个等待队列 等待队列项*/
if(atomic_read(&dev->releasekey) == 0) { /* 没有按键按下 */
add_wait_queue(&dev->r_wait, &wait); /* 将等待队列项 添加到等待队列头 */
__set_current_state(TASK_INTERRUPTIBLE);/* 设置任务状态 */
schedule(); /* 进行一次任务切换 */
if(signal_pending(current)) { /* 判断是否为信号引起的唤醒 */
ret = -ERESTARTSYS;
goto wait_error;
}
}
remove_wait_queue(&dev->r_wait, &wait); /* 唤醒以后将等待队列移除 */
keyvalue = atomic_read(&dev->keyvalue);
releasekey = atomic_read(&dev->releasekey);
修改代码:将keyvalue和releasekey 赋值语句 往前提,并采用releasekey 进行休眠判断,代码如下:
DECLARE_WAITQUEUE(wait, current); /* 定义一个等待队列 等待队列项*/
keyvalue = atomic_read(&dev->keyvalue);
releasekey = atomic_read(&dev->releasekey);
if(releasekey == 0) { /* 没有按键按下 */
add_wait_queue(&dev->r_wait, &wait); /* 将等待队列项 添加到等待队列头 */
__set_current_state(TASK_INTERRUPTIBLE);/* 设置任务状态 */
schedule(); /* 进行一次任务切换 */
if(signal_pending(current)) { /* 判断是否为信号引起的唤醒 */
ret = -ERESTARTSYS;
goto wait_error;
}
}
remove_wait_queue(&dev->r_wait, &wait); /* 唤醒以后将等待队列移除 */
这时候编译,并在目标板中加载模块,执行应用程序,按下按键后 控制台打印如下错误:
Unable to handle kernel NULL pointer dereference at virtual address 00000004
pgd = 88728000
[00000004] *pgd=884a3831, *pte=00000000, *ppte=00000000
Internal error: Oops: 817 [#1] PREEMPT SMP ARM
Modules linked in: blockio(O)
CPU: 0 PID: 75 Comm: imx6uirqApp Tainted: G O 4.1.15 #1
Hardware name: Freescale i.MX6 Ultralite (Device Tree)
task: 884f8980 ti: 8873e000 task.ti: 8873e000
PC is at remove_wait_queue+0x20/0x48
LR is at get_parent_ip+0x10/0x2c
pc : [<80066878>] lr : [<80057274>] psr: 600d0093
sp : 8873fec8 ip : 00100100 fp : 00000000
r10: 00000000 r9 : 8873e000 r8 : 8000f684
r7 : 00000004 r6 : 7ecd7d08 r5 : 7f000570 r4 : 8873fedc
r3 : 00000000 r2 : 00000000 r1 : 00200200 r0 : 200d0013
Flags: nZCv IRQs off FIQs on Mode SVC_32 ISA ARM Segment user
Control: 10c5387d Table: 8872806a DAC: 00000015
Process imx6uirqApp (pid: 75, stack limit = 0x8873e210)
Stack: (0x8873fec8 to 0x88740000)
fec0: 7f0004dc 00000001 7ecd7d08 7f000130 8173e000 00000000
fee0: 884f8980 80059034 00000000 00000000 884a6180 7f000070 8873ff88 800ea904
ff00: 88750015 76f81000 00000000 860f9660 88742028 00000101 00000000 00000040
ff20: 00000001 00000020 88001b80 80973210 8bc65a00 88750000 8873ff40 800e4d4c
ff40: 80974754 7ecd7d08 884a6180 7ecd7d08 884a6180 8873ff88 00000004 800eb0a8
ff60: 00000000 800ea498 00000000 884a6180 884a6180 7ecd7d08 00000004 8000f684
ff80: 8873e000 800eb948 00000000 00000000 00000000 7ecd7d38 00000000 00000000
ffa0: 00000003 8000f500 7ecd7d38 00000000 00000003 7ecd7d08 00000004 7ecd7d08
ffc0: 7ecd7d38 00000000 00000000 00000003 00000000 00000000 76f81000 00000000
ffe0: 00000000 7ecd7cfc 000104c3 76ef3f66 600d0030 00000003 8bf5e821 8bf5ec21
[<80066878>] (remove_wait_queue) from [<7f000130>] (imx6uirq_read+0xc0/0x148 [blockio])
[<7f000130>] (imx6uirq_read [blockio]) from [<800ea904>] (__vfs_read+0x20/0xd4)
[<800ea904>] (__vfs_read) from [<800eb0a8>] (vfs_read+0x7c/0x104)
[<800eb0a8>] (vfs_read) from [<800eb948>] (SyS_read+0x44/0x9c)
[<800eb948>] (SyS_read) from [<8000f500>] (ret_fast_syscall+0x0/0x3c)
Code: e5943010 e594200c e59f1020 e59fc020 (e5823004)
---[ end trace d86b1eaea8c25eeb ]---
note: imx6uirqApp[75] exited with preempt_count 1
Segmentation fault
百思不得解,为什么把赋值语句 拿到前面会报段错误,并没有涉及指针的赋值啊,而且和之前的语句代码逻辑并没有任何区别啊。求解释
|
|