BUG: Bad page map in process XXX pte:800000036fae6227 pmd:35be8c067

来源:互联网 发布:萌拍相机软件 编辑:程序博客网 时间:2024/06/07 02:23

首先给出内核的打印信息,串口会有一些,dmesg看的会全一些。

BUG: Bad page map in process XXX pte:800000036fae6227 pmd:35be8c067addr:00007f3fa75c0000 vm_flags:00200070 anon_vma:(null) mapping:(null) index:7f3fa75c0Pid: 1312, comm: XXX Not tainted 2.6.32.27 #1Call Trace: [<ffffffff815a3570>] print_bad_pte+0x1e2/0x1fb [<ffffffff811063ee>] vm_normal_page+0x6e/0x80 [<ffffffff81107117>] unmap_vmas+0x5b7/0x9f0 [<ffffffff8106edba>] ? dequeue_signal+0xda/0x170 [<ffffffff8110cb5c>] unmap_region+0xcc/0x170 [<ffffffff8110e405>] do_munmap+0x305/0x3a0 [<ffffffff8110f183>] sys_munmap+0x53/0x80 [<ffffffff8100c082>] system_call_fastpath+0x16/0x1bDisabling lock debugging due to kernel taint

堆栈中的内核版本号不必关注,因为换成3.16.44的内核也会出现这个问题。

这个堆栈似乎提供了很多的信息,可是对于定位问题,没有太多的帮助,并且一度诱导了错误了方向。

堆栈分析:这个堆栈明显是一个系统调用,系统调用的接口函数为munmap(),在程序代码中搜索,只找到几处,分析代码好像看不出什么问题。于是在进程中挂断点,由于堆栈每次都出现在业务线程,所以将所有的业务线程在munmap()挂上断点:break munmap thread idx,然后break munmap thread idy … ,触发断点,不是每次触发断点都会出现堆栈的,触发几次后才会出现。这个现象开始怀疑是内核的内存出现问题了。直到设了一个display *(0x00007f3fa75c0000),每次munmap()断点触发,都会试图读取 *(0x00007f3fa75c0000)的值,在某一次中断触发后,直接打印了上述堆栈(没有设置display前都是continue然后munmap()触发打印的),更确定是内核内存出问题了。

本着首先相信内核,怀疑自己的心态,首先定位驱动的问题,首先想到的是netmap驱动。查看进程XXX的内存映射:cat /proc/1312/maps

...7f4020021000 default7f40275c0000 default file=/dev/Vnetmap7f40a8000000 default anon=3 dirty=3 N0=37f40a8021000 default...

有没有惊奇的发现0x7f40275c0000 - 0x00007f3fa75c0000 = 0x80000000,也就是netmap的映射地址减去出问题的映射地址(就是上边display的那个)等于2G。每次都这么准。一脸懵逼,想着这事内核啥机制导致的,于是走读了一下内核内存管理的代码,重点关注了一下mmap()系统调用的流程。大概先屡一下思路。mmap()系统调用的流程简单如下:

do_mmap_pgoff   |   |--get_unmapped_area   |--...   |--mmap_region        |        |--find_vma_repare        |--...        |--file->f_op->mmap        |--...

上边的file->f_op->mmap是特定与文件的函数,还记的上边的设备文件/dev/Vnetmap当用户程序打开它,并把它的文件描述符fd给了mmap()后就可调到Vnetmap自定义的file->f_op->mmap了。他是在Vnetmap驱动中实现,问题就是出在这里了。

分析:运行环境为64位X86平台。Vnetmap是驱动模块,运行在内核态,它将内核中申请的内存一点点映射到用户虚拟地址空间。它使用了一个int类型的变量作为虚拟地址偏移的累计计数,在偏移超过2G之后,int发生符号翻转变成负数了,偏移就变成-2G,这似乎就跟上边联系起来了。

理解:(这部分没跟源码,纯分析仅供说服自己,其实是没有太多时间了,还要干别的,有时间再分析吧)超出2G的内核空间内存,实际跟页表关联(错误关联),但在页面的区域(eara)中不可见,发生错误关联的用户态空间被重新分配时,发现页表意见被关联到页框,打印上述错误。


Contact: bigjordon@163.com