在GDB中无法访问[vvar]内存区域的内容?

7

我正在Linux下使用GDB实时调试进程,但我发现无法读取/proc/${PID}/maps中定义的内存区域的内容,如下所示:

3aaef123000-3aaef125000 r--p 00000000 00:00 0                            [vvar]

显然,r--p中的r标志表示它是可读的,但是GDB总是告诉我无法访问该内存区域的内容,例如:

警告:无法在<address>处访问<count>字节的目标内存,停止搜索。

[vvar]内存区域到底是什么?为什么我不能从GDB中读取它的内容?

编辑:可能有助于回答问题的外部资源:

  • 实现虚拟系统调用 - 一篇旧的(2014年10月)和很可能已过时的LWN文章提到了[vvar]部分。没有理解其中的一半。
  • vvar,gup && coredump - 一个内核邮件列表线程(2015年3月),讨论似乎是相同问题。也没有理解。

如果有人能以更简单的方式向我解释这个问题,我将不胜感激。

1个回答

9

什么是[vvar]内存区域?

在这里解释

为什么我无法从GDB中读取它的内容?

这听起来像是内核ptrace实现中的一个bug:如果进程可以读取数据,那么进程的追踪器(如GDB)也应该可以。但并不总是这样。例如,GDB可以检查栈保护页,而进程本身无法访问它们(即这是内核反向错误)。

更新:

如果有人能用简单的语言解释一下,我会很感激。

实际上并没有太多内容:为了更快地实现某些简单的系统调用(例如gettimeofday),内核将一些内核数据暴露给用户级进程非常方便,这正是它所做的:在每个进程的某个地址上“神奇地”映射了一页(或两页)内核数据,并提供了一种方法让用户进程找到该页面出现的虚拟地址。
其余大部分都是不相关的实现细节。
您可能还会发现VDSO页面的this explanation有帮助(它是关于代码而不是数据,但思想基本相同)。

很不幸,我发现场外的解释并没有很好地解释[vvar]部分。正如在该页面上由luto在评论中所述,“不幸的是,这有点过时了——x86 vvar机制在3.16中得到了重大改进。” - jotik
@jotik,我已经更新了回答。当您只是尝试理解该功能时,机制已经被大幅重制这一事实是不相关的。 - Employed Russian

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接