免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 4109 | 回复: 19
打印 上一主题 下一主题

帮忙看一个oops 发生在rmmod的时候 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2012-03-06 16:36 |只看该作者 |倒序浏览
[  590.464272] BUG: unable to handle kernel NULL pointer dereference at   (null)
[  590.464670] IP: [<c1185b3c>] remove_files.clone.1+0xc/0x30
[  590.465059] *pde = 172d4067 *pte = 00000000
[  590.465422] Oops: 0000 [#1] SMP
[  590.465490] last sysfs file: /sys/devices/pci0000:00/0000:00:10.0/host2/target2:0:0/2:0:0:0/block/sda/sda1/uevent
[  590.465490] Modules linked in: vmblock vesafb binfmt_misc snd_ens1371 gameport snd_ac97_codec ac97_bus snd_pcm snd_seq_midi snd_rawmidi snd_seq_midi_event snd_seq ppdev snd_timer snd_seq_device vmw_balloon psmouse parport_pc serio_raw snd soundcore snd_page_alloc shpchp lp i2c_piix4 parport mptspi mptscsih floppy mptbase scsi_transport_spi vmxnet [last unloaded: memdev]
[  590.465490]
[  590.465490] Pid: 1960, comm: rmmod Not tainted 2.6.38-8-generic #42-Ubuntu VMware, Inc. VMware Virtual Platform/440BX Desktop Reference Platform
[  590.465490] EIP: 0060:[<c1185b3c>] EFLAGS: 00010206 CPU: 0
[  590.465490] EIP is at remove_files.clone.1+0xc/0x30
[  590.465490] EAX: e8018270 EBX: e80ecc00 ECX: 00000000 EDX: 00000000
[  590.465490] ESI: e8018270 EDI: eb9bb068 EBP: e80d3ef4 ESP: e80d3eec
[  590.465490]  DS: 007b ES: 007b FS: 00d8 GS: 00e0 SS: 0068
[  590.465490] Process rmmod (pid: 1960, ti=e80d2000 task=e8ee3f20 task.ti=e80d2000)
[  590.465490] Stack:
[  590.465490]  e80ecc00 e8018270 e80d3f1c c1185e8a 00000282 00000000 d71066c0 00000070
[  590.465490]  e80d3f1c d722af54 eb9bb020 00000070 e80d3f34 c1086bd2 eb9bb068 eb9bb020
[  590.465490]  00000880 00000000 e80d3f44 c1087a1a eb9bb020 00000880 e80d3fac c1087c1c
[  590.465490] Call Trace:
[  590.465490]  [<c1185e8a>] sysfs_remove_group+0x3a/0xd0
[  590.465490]  [<c1086bd2>] mod_sysfs_teardown+0xf2/0x120
[  590.465490]  [<c1087a1a>] free_module+0x3a/0xd0
[  590.465490]  [<c1087c1c>] sys_delete_module+0x16c/0x1f0
[  590.465490]  [<c1104d9e>] ? do_munmap+0x1fe/0x280
[  590.465490]  [<c11048e0>] ? arch_unmap_area_topdown+0x0/0x20
[  590.465490]  [<c1509bf4>] syscall_call+0x7/0xb
[  590.465490] Code: 75 c5 b8 44 54 75 c1 e8 c3 27 38 00 83 c4 0c 5b 5d c3 90 90 90 90 90 90 90 90 90 90 90 90 90 55 89 e5 56 53 3e 8d 74 26 00 89 c6 <8b> 02 89 d3 85 c0 74 18 8d 74 26 00 8b 08 31 d2 83 c3 04 89 f0
[  590.465490] EIP: [<c1185b3c>] remove_files.clone.1+0xc/0x30 SS:ESP 0068:e80d3eec
[  590.465490] CR2: 0000000000000000
[  590.503617] ---[ end trace cf63a6a7692048dd ]---

论坛徽章:
6
金牛座
日期:2013-10-08 10:19:10技术图书徽章
日期:2013-10-14 16:24:09CU十二周年纪念徽章
日期:2013-10-24 15:41:34狮子座
日期:2013-11-24 19:26:19未羊
日期:2014-01-23 15:50:002015年亚洲杯之阿联酋
日期:2015-05-09 14:36:15
2 [报告]
发表于 2012-03-07 09:41 |只看该作者
回复 1# win1naruto
EIP: [<c1185b3c>] remove_files.clone.1+0xc/0x30 SS:ESP 0068:e80d3eec

如果内核编译选择debug,通过这行信息和gdb可以直接定位到具体的代码行的。
   

论坛徽章:
0
3 [报告]
发表于 2012-03-07 09:44 |只看该作者
回复 2# 瀚海书香


    也就是把内核调成dubug模式??这个太烦了,有木有其他办法

论坛徽章:
0
4 [报告]
发表于 2012-03-07 11:49 |只看该作者
瀚海书香 发表于 2012-03-07 09:41
回复 1# win1naruto

如果内核编译选择debug,通过这行信息和gdb可以直接定位到具体的代码行的。


二楼说的应该是最准的方法了。还是一个方法就是猜EIP所在的函数及调用的子函数里哪里可能存在的空指针。

论坛徽章:
0
5 [报告]
发表于 2012-03-07 13:32 |只看该作者
瀚海书香 发表于 2012-03-07 09:41
回复 1# win1naruto

如果内核编译选择debug,通过这行信息和gdb可以直接定位到具体的代码行的。


也就是把gdb补丁打到内核上去是吧

论坛徽章:
6
金牛座
日期:2013-10-08 10:19:10技术图书徽章
日期:2013-10-14 16:24:09CU十二周年纪念徽章
日期:2013-10-24 15:41:34狮子座
日期:2013-11-24 19:26:19未羊
日期:2014-01-23 15:50:002015年亚洲杯之阿联酋
日期:2015-05-09 14:36:15
6 [报告]
发表于 2012-03-07 15:26 |只看该作者
回复 5# win1naruto
也就是把gdb补丁打到内核上去是吧

不需要的,只有编译的时候选择了-g就可以了。

   

论坛徽章:
0
7 [报告]
发表于 2012-03-07 15:53 |只看该作者
瀚海书香 发表于 2012-03-07 09:41
回复 1# win1naruto

如果内核编译选择debug,通过这行信息和gdb可以直接定位到具体的代码行的。


试试addr2line

论坛徽章:
2
CU十二周年纪念徽章
日期:2013-10-24 15:41:34处女座
日期:2013-12-27 22:22:41
8 [报告]
发表于 2012-03-07 21:14 |只看该作者
我猜是你模块的卸载函数调用了sysfs_remove_group,而第二个参数struct attribute_group的attrs成员为NULL。

裸分析的话,可以这样:
1. 75 c5 b8 44 54 75 c1 e8 c3 27 38 00 83 c4 这一串是闯祸IP附近的指令,<8b>应该就是犯事IP地址里第一个字节,把它们存为二进制文件。

  1. for i in 75 c5 b8 44 54 75 c1 e8 c3 27 38 00 83 c4 0c 5b 5d c3 90 90 90 90 90 90 90 90 90 90 90 90 90 55 89 e5 56 53 3e 8d 74 26 00 89 c6 8b 02 89 d3 85 c0 74 18 8d 74 26 00 8b 08 31 d2 83 c3 04 89 f0 ; do
  2.        printf "\x$i" >> obj;
  3. done
复制代码
2. 反汇编之。
  1. objdump -mx86 -bbinary -D obj
复制代码
3.对照提示的函数与反汇编代码查找问题:
  1.   1f:        55                           push   %ebp
  2.   20:        89 e5                        mov    %esp,%ebp
  3.   22:        56                           push   %esi
  4.   23:        53                           push   %ebx
  5.   24:        3e 8d 74 26 00               lea    %ds:0x0(%esi,%eiz,1),%esi
  6.   29:        89 c6                        mov    %eax,%esi
  7.   2b:        8b 02                        mov    (%edx),%eax
  8.   2d:        89 d3                        mov    %edx,%ebx
  9.   2f:        85 c0                        test   %eax,%eax
  10.   31:        74 18                        je     0x4b
  11.   33:        8d 74 26 00                  lea    0x0(%esi,%eiz,1),%esi
  12.   37:        8b 08                        mov    (%eax),%ecx
  13.   39:        31 d2                        xor    %edx,%edx
  14.   3b:        83 c3 04                     add    $0x4,%ebx
  15.   3e:        89 f0                        mov    %esi,%eax
复制代码
出错指令8b 02是mov    (%edx),%eax   。即EDX为零。再看源代码:
  1.   19static void remove_files(struct sysfs_dirent *dir_sd, struct kobject *kobj,
  2.   20                         const struct attribute_group *grp)
  3.   21{
  4.   22        struct attribute *const* attr;
  5.   23        int i;
  6.   24
  7.   25        for (i = 0, attr = grp->attrs; *attr; i++, attr++)
  8.   26                sysfs_hash_and_remove(dir_sd, NULL, (*attr)->name);
  9.   27}
复制代码
下面几条比较亮:
  2b:        8b 02                        mov    (%edx),%eax
  2d:        89 d3                        mov    %edx,%ebx
  2f:        85 c0                        test   %eax,%eax
  31:        74 18                        je     0x4b
  3b:        83 c3 04                     add    $0x4,%ebx
edx的值和[edx]值都被用到了,edx大概是grp->attrs, [edx]就是*attr,[edx]被放到eax里然后会判断eax是否为0,大概就是for中间的条件判断,ebx加4就是attr++。所以是grp->attrs为NULL导致*attr出错。

有好的调试工具的话当然更方便,如果可以用addr2line可能一下就可以指出for那一行。这样瞎掰反正也讲得通,对不对就不知道了。

论坛徽章:
0
9 [报告]
发表于 2012-03-08 01:30 |只看该作者
tempname2 发表于 2012-03-07 21:14
我猜是你模块的卸载函数调用了sysfs_remove_group,而第二个参数struct attribute_group的attrs成员为NULL。 ...


这位同学很给力啊...

论坛徽章:
0
10 [报告]
发表于 2012-03-08 15:49 |只看该作者
tempname2 发表于 2012-03-07 21:14
我猜是你模块的卸载函数调用了sysfs_remove_group,而第二个参数struct attribute_group的attrs成员为NULL。 ...

其实我是参照这个驱动:http://apps.hi.baidu.com/share/detail/33924984
划分一块内存来当设备读写,这个内存buffer大小是1024,我故意copy_from_user(buffer,source,4096);也就是故意写多很多数据进去,printk没有显著的问题,也没有奔溃,就是最后rmmod有问题,这个让我很费解。。。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP