GDB无法访问mmap()内核分配的内存?
我遇到了GDB和内核空间中分配的一些缓冲区的问题。缓冲区由内核模块分配,内核模块应该分配连续的内存块,然后通过mmap()调用将内存映射到用户空间。然而,GDB似乎无法随时访问这些块。例如,创GDB断点后:GDB无法访问mmap()内核分配的内存?
(gdb) x /10xb 0x4567e000
0x4567e000: Cannot access memory at address 0x4567e000
然而,看着应用程序的当前映射的内存区域在/ proc // smaps显示:
4567e000-456d3000 rwxs 8913f000 00:0d 883 /dev/cmem
Size: 340 kB
Rss: 340 kB
Pss: 0 kB
Shared_Clean: 0 kB
Shared_Dirty: 0 kB
Private_Clean: 0 kB
Private_Dirty: 0 kB
Referenced: 0 kB
Swap: 0 kB
的原因,我甚至看这是因为在运行过程中的某个时刻,这个缓冲区地址(或者以类似方式分配的另一个地址)会导致SIGSEGV。
Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x49aea490 (LWP 652)]
0x402e4ea8 in fwrite() from /lib/libc.so.6
(gdb)
(gdb)
(gdb) where
#0 0x402e4ea8 in fwrite() from /lib/libc.so.6
#1 0x000eb394 in EncryptedWriter::Write (this=0x198600, buffRaw=0x4567e000 <Address 0x4567e000 out of bounds>, iLenRaw=719) at encrypted_writer.cpp:397
#2 0x0006b0f4 in EncryptionWrapper::Write (this=0x3ab2698, buffer=0x4567e000, size=719) at encryption.cpp:54
该段错误发生,尽管该缓冲区已被大量使用,直到崩溃的事实,并在/ proc // smaps文件还表示要为上述映射此缓冲区。
我完全不知道为什么会出现这种情况,为什么映射在/ proc中看起来有效,但从来没有在GDB中有效。
关于为什么gdb无法访问你想要的内存,我相信Linux不会通过ptrace()访问I/O内存。根据cmemk.c(我在linuxutils_2_25.tar.gz中找到),mmap()确实在所讨论的内存中设置了VM_IO标志。
要从gdb访问此内存,请在程序中添加一个读取此内存并使gdb调用此函数的函数。
好的,我没有意识到这个限制,并且cmem确实设置了VM_IO(就像/ dev/mem的驱动程序一样,所以这很有意义)。谢谢。 任何想法为什么GDB会声明地址超出堆栈帧1的边界而不是堆栈帧2? – 2010-09-03 23:54:31
这可能是你正在寻找的错误。 1. Wrapper()得到一个有效的指针2.另一个线程(或Wrapper(),不太可能)释放这个指针3. Wrapper()仍然将这个指针传递给Writer()4. Writer()将这个指针传递给fwrite() 5. fwrite()使用这个指针并死掉 – sigjuice 2010-09-04 00:19:56
实际上,缓冲区地址是一个全红鲱鱼。原来另一个线程正在关闭文件指针,所以fwrite因此死亡。在线程拆卸后,缓冲区本身不会被释放,直到进程关闭。谢谢您的帮助! – 2010-09-04 02:43:48
请参阅examining-mmaped-addresses-using-gdb讨论在另一个线程中,尤其是答案here。您应该能够在模块的mmap实现中为您的VMA添加自定义vm_operations_struct
。
另请参阅Linux内核中的mm/memory.c。当get_user_pages()
失败时,代码将尝试调用驱动程序中的自定义vma->vm_ops->access
实现来访问内存。
因此,你的应用程序段错误,而它试图访问此映射*和* gdb说,它无法访问映射吗?难道由于某种原因映射变得无法访问,而/ proc/smaps只是不显示这个?这是哪个内核模块? – 2010-09-03 22:56:41
是的,但GDB在segfault之前甚至无法访问映射,就我所知,它也无法在任何时候访问此内核模块的任何映射。我认为可能映射变得无法访问,但我对内核内存管理知之甚少,不知道可能是什么原因,以及为什么/ proc/smaps不能反映这种变化。分配这些模块的模块是德州仪器的连续存储器(CMEM)模块。它与CodecEngine API一起使用,用于管理目标为不具有MMU的协处理器的缓冲区。 – 2010-09-03 23:04:30