Linux - 从内核空间中的用户空间的线程访问mmap()ed内存

时间:2017-10-16 07:37:19

标签: linux memory-management linux-kernel kgdb

在我的用户空间线程中映射此内存:

b7fd0000-b7fd1000 rwxp 00000000 00:00 0 

线程正在运行(无限循环)

在内核中创建一个断点并尝试访问它:

Thread 466 received signal SIGTRAP, Trace/breakpoint trap.
[Switching to Thread 3908]
0xc10d4060 in kgdb_breakpoint ()
(gdb) x/01i 0xb7fd0000
   0xb7fd0000:  Cannot access memory at address 0xb7fd0000

但它无法访问。

如何从内核空间访问0xb7fd0000?会有什么地址?

甚至可能吗?

谢谢,

3 个答案:

答案 0 :(得分:1)

内存将出现的地址取决于当前映射的用户空间上下文。

这种方式的工作方式是,一些虚拟地址保留给内核,并且在所有上下文中都是相同的。这就是为什么你可以在内核地址上设置断点而不必担心当前映射的用户空间进程。

对于用户空间,情况并非如此。每次映射新进程时,US的虚拟地址都会完全更改。

这可能是X-Y问题。您正在尝试做某事,并且认为内核级别断点是您希望实现的目标。

猜测一下,您希望内核驱动程序能够与您的用户空间线程进行通信。如果是这种情况,最好的办法是导出一个角色设备,并让用户空间打开它并从那里打开mmap(而不仅仅是一个匿名的mmap)。然后,您可以控制它接收的内存,从而将其映射到指针稳定的内核地址空间。

答案 1 :(得分:0)

我不是kgdb的专家,但是在断点被击中时需要检查current->pid,包含你正在跟踪的进程的pid。这是因为虽然内核空间内的内存位置已被命中,但用户空间进程可能不是您感兴趣的进程。为了防止页面被换出的可能性,使用{{1来锁定映射页面可能更安全}}

答案 2 :(得分:0)

至少有两件事需要注意。

  1. When to break。如果你只是在内核调试器中点击crtl-C,你就不知道用户空间的上下文是什么。它可以是任何用户空间进程。您希望内核调试器暂停并让您控制何时用户空间上下文引用您感兴趣的进程。执行此操作的一种方法如下: - 如果您能够重新编译内核,请添加新的系统调用。在mmap的区域之后,从用户空间进程调用此系统调用。在新添加的系统调用上放置断点后开始调试内核。当断点被击中时,您知道用户空间上下文是您感兴趣的进程的上下文。
  2. Virtual memory late binding。即使您按照[1]中的步骤操作,如果您没有在该位置读取/写入任何内容,在访问用户空间中的缓冲区内容时仍会遇到问题。确保在mmap的区域之后,您可以在调用新添加的系统调用之前读取或写入mmap'd位置。