KERNEL BUG: unable to handle kernel NULL pointer dereference at 00000004
来源:互联网 发布:淘宝怎么改身份证号码 编辑:程序博客网 时间:2024/05/16 19:55
出现kenel BUG信息:
BUG: unable to handle kernel NULL pointer dereference at 00000004
IP: [<c12c2c45>] firmware_loading_store+0x55/0x170
*pdpt = 0000000018ea2001 *pde = 0000000000000000
Oops: 0000 [#1] PREEMPT SMP
last sysfs file: /sys/devices/fw_device/firmware/fw_device/loading
Pid: 3509, comm: osal_fw_hotplug Not tainted 2.6.39 #3
EIP: 0060:[<c12c2c45>] EFLAGS: 00010282 CPU: 0
EIP is at firmware_loading_store+0x55/0x170
EAX: 00000000 EBX: d8968c00 ECX: 00000000 EDX: 1c0c6000
ESI: d8968c40 EDI: d93d0960 EBP: ffffffed ESP: d8c4bf20
DS: 007b ES: 007b FS: 00d8 GS: 0033 SS: 0068
Process osal_fw_hotplug (pid: 3509, ti=d8c4a000 task=d9c86130 task.ti=d8c4a000)
Stack:
00000161 80000000 000000d0 d89a0b00 c12c2bf0 00000002 d8ed3c30 c12b7765
00000002 c15a4e0c 00000002 c1101826 00000002 08063188 d9736b14 c15a4e0c
d8968c48 d9296d00 00000002 08063188 c1101780 c10b4d40 d8c4bf9c d89a0b00
Call Trace:
[<c12c2bf0>] ? firmware_class_timeout+0x10/0x10
[<c12b7765>] ? dev_attr_store+0x25/0x40
[<c1101826>] ? sysfs_write_file+0xa6/0x100
[<c1101780>] ? sysfs_poll+0x80/0x80
[<c10b4d40>] ? vfs_write+0xa0/0x140
[<c10b4fe1>] ? sys_write+0x41/0x80
[<c154e9d1>] ? syscall_call+0x7/0xb
Code: 04 e8 80 08 de ff 8b 53 1c 31 c9 8b 43 18 8b 7b 10 c7 04 24 61 01 00 00 c7 44 24 04 00 00 00 80 e8 81 08 de ff 89 47 04 8b 43 10 <8b> 50 04 85 d2 0f 84 ec 00 00 00 8b 53 18 89 50 08 89 d8 c7 43
EIP: [<c12c2c45>] firmware_loading_store+0x55/0x170 SS:ESP 0068:d8c4bf20
CR2: 0000000000000004
如何调试?
这种情况下,应该是出现了kernel NULL指针,出现空指针有可能导致内核出现上述的错误信息,或者更严重的会出现Ooops,kernel panic.只关上讲,从上面的出错信息中可以了解到,出错函数位于:IP: [<c12c2c45>] firmware_loading_store+0x55/0x170,函数体大小大约为0x170,大约位于0x55的offset.
在kernel底下找到此函数,位于driver/base/firmware_class.c,这个是用于sysfs,用来进行fimrware 读写的接口。
这里涉及到注册到sysfs的接口:
static DEVICE_ATTR(loading, 0644, firmware_loading_show, firmware_loading_store);
#define DEVICE_ATTR(_name, _mode, _show, _store) \
struct device_attribute dev_attr_##_name = __ATTR(_name, _mode, _show, _store)
其节点使用函数:device_create_file(f_dev, &dev_attr_loading)来创建,然后使用uevent 来产生一个udev add的动作,kobject_uevent(&fw_priv->dev.kobj, KOBJ_ADD);
kenel path A接着就进入了休眠状态,并等待一个60s的定时器超时:
mod_timer(&fw_priv->timeout,
round_jiffies_up(jiffies +
loading_timeout * HZ));===》其作用是添加定时器
wait_for_completion(&fw_priv->completion);===》等待firmware完成,需要其它进程给出一个完成的信号才可以继续往下
kernel path B(udev)被触发,进行fimrware的loading动作
SUBSYSTEM=="firmware", ACTION=="add", RUN+="/lib/udev/osal_fw_hotplug.sh"
其中/lib/udev/osal_fw_hotplug.sh脚本如下
# Trigger the start of the loading process
echo 1 >/sys/$DEVPATH/loading
sleep 2
# Load the FW file
cat "$FIRMWARE" > /sys/$DEVPATH/data
RET_VAL=$?
sleep 2
# Check the return code; if it failed, report the failure.
if [ $RET_VAL -ne 0 ]; then
echo -1 >/sys/$DEVPATH/loading
else
echo 0 >/sys/$DEVPATH/loading
fi
exit 0
问题就处在firmware_loading_store这个函数!!!
static ssize_t firmware_loading_store(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
{
struct firmware_priv *fw_priv = to_firmware_priv(dev);
int loading = simple_strtol(buf, NULL, 10);
int i;
switch (loading) {
case 1:
printk("Trigle to loading value:%d \n",loading);
mutex_lock(&fw_lock);
if (!fw_priv->fw) {
mutex_unlock(&fw_lock);
break;
}
firmware_free_data(fw_priv->fw);
memset(fw_priv->fw, 0, sizeof(struct firmware));
/* If the pages are not owned by 'struct firmware' */
for (i = 0; i < fw_priv->nr_pages; i++)
__free_page(fw_priv->pages[i]);
kfree(fw_priv->pages);
fw_priv->pages = NULL;
fw_priv->page_array_size = 0;
fw_priv->nr_pages = 0;
set_bit(FW_STATUS_LOADING, &fw_priv->status);
mutex_unlock(&fw_lock);
break;
case 0:
mutex_lock(&fw_lock);
printk("Begin to loading value:%d \n",loading);
if (test_bit(FW_STATUS_LOADING, &fw_priv->status)) {
vunmap(fw_priv->fw->data);
fw_priv->fw->data = vmap(fw_priv->pages,
fw_priv->nr_pages,
0, PAGE_KERNEL_RO);
if (!fw_priv->fw->data) {
dev_err(dev, "%s: vmap() failed\n", __func__);
mutex_unlock(&fw_lock);
goto err;
}
/* Pages are now owned by 'struct firmware' */
fw_priv->fw->pages = fw_priv->pages;
fw_priv->pages = NULL;
fw_priv->page_array_size = 0;
fw_priv->nr_pages = 0;
clear_bit(FW_STATUS_LOADING, &fw_priv->status);
complete(&fw_priv->completion); /*这一步,如果成功完成了,在发送complete命令给kenel path A*/
/*clear_bit(FW_STATUS_LOADING, &fw_priv->status);*/
}
else if(test_bit(FW_STATUS_DONE,&fw_priv->status))
{
printk("Loading status is %d\n",fw_priv->status);
}
mutex_unlock(&fw_lock); /*在此地必须加锁,并且判定此时firmware的状态,因为,firmware的状态有可能不是LOADING,而是DONE的状态,造成NULL 指针*/
break ;
/* fallthrough */
default:
dev_err(dev, "%s: unexpected value (%d)\n", __func__, loading);
/* fallthrough */
case -1:
err:
printk("loading firmware abort,file:%s,line:%d!\n",__FILE__,__LINE__);
fw_load_abort(fw_priv);
break;
}
/*return count;*/
return count;
}
kernel path A 在接到completion信号后,被唤醒,设置状态,并删除定时器:
set_bit(FW_STATUS_DONE, &fw_priv->status);
del_timer_sync(&fw_priv->timeout);
这里需要略微提一下设置bit的这个函数。。。
- KERNEL BUG: unable to handle kernel NULL pointer dereference at 00000004
- Kernel OOPS: BUG: unable to handle kernel NULL pointer dereference
- unable to handle kernel null pointer dereference at virtual address
- Unable to handle kernel NULL pointer dereference.
- Unable to handle kernel NULL pointer dereference.
- Oops: Unable to handle kernel NULL pointer dereference at virtual address 00000004
- 介绍Unable to handle kernel NULL pointer dereference...
- 解决Unable to handle kernel NULL pointer dereference
- oops 消息 Unable to handle kernel NULL pointer dereference at virtual address
- Unable to handle kernel NULL pointer dereference at virtual address-----------原因分析 ,及解决办法
- 操作寄存器错误Unable to handle kernel NULL pointer dereference at virtual address的解决办法
- Unable to handle kernel NULL pointer dereference at virtual address 0000错误解决
- oops 消息 Unable to handle kernel NULL pointer dereference at virtual address .
- Unable to handle kernel NULL pointer dereference at virtual address 00000058的错误解决
- oops 消息 Unable to handle kernel NULL pointer dereference at virtual address
- Unable to handle kernel NULL pointer dereference at virtual address 00000000问题的解决
- Unable to handle kernel NULL pointer dereference at virtual address 00000031
- 驱动开发误用指针错误:Unable to handle kernel NULL pointer dereference at virtual address
- httpd: apr_sockaddr_info_get() failed for apache
- ArcGIS Flex API 调用天地图和Google地图服务
- ListView的虚拟模式
- 2.6 scopy
- Python NLTK提取有用的chunk
- KERNEL BUG: unable to handle kernel NULL pointer dereference at 00000004
- 行内视图(重点)
- request.getRealPath不推荐使用request.getRealPath("") 这个方法已经不推荐使用了
- 2.5 FillString
- HDU——2056——Rectangles
- jQuery EasyUI 的EasyLoader功能介绍
- TestNG的参数化测试
- 汇编语言学习——第一章 基础知识
- JavaScript绝句的小研究