GDB无法访问mmap()'d内核分配的内存?

时间:2010-09-03 22:52:45

标签: c++ c gdb mmap

我遇到了GDB问题和内核空间中分配的一些缓冲区。缓冲区由内核模块分配,内核模块应该分配连续的内存块,然后通过mmap()调用将内存映射到用户空间。但是,GDB似乎无法随时访问这些块。例如,在GDB中遇到断点后:

(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中有效。

2 个答案:

答案 0 :(得分:5)

关于为什么gdb无法访问你想要的内存,我相信Linux不能通过ptrace()访问I / O内存。

根据cmemk.c(我在linuxutils_2_25.tar.gz中找到),mmap()确实在相关内存上设置了VM_IO标志。

要从gdb访问此内存,请在程序中添加一个读取此内存并让gdb调用此函数的函数。

答案 1 :(得分:0)

请参阅另一个主题中的examining-mmaped-addresses-using-gdb讨论,尤其是答案here。您应该可以在模块的mmap实现中向自己的VMA添加自定义vm_operations_struct

另请参阅Linux内核中的mm/memory.c。当get_user_pages()失败时,代码将尝试调用驱动程序中的自定义vma->vm_ops->access实现来访问内存。