2

下面是我努力的细节,它们仅与我的问题部分相关:

在内核版本为 2.6.37.6 的嵌入式 linux (arm) 上的 /proc/pid/maps 映射中,第一行的偏移量(可执行文件本身的代码段)似乎是错误的。

我总是看到这样的一行:

00008000-00061000 r-xp 00000000 00:10 8073509 myprog

(范围是进程地址空间中的地址,权限后面的数字应该是文件的偏移量)

但是,实际偏移量似乎是 0x8000 - 至少,使用此假设的解释看起来更可信。nm 告诉我 myprog 在 0x8000 之前没有代码,所以这也是有道理的。

有人可以指点我在哪里可以找到更多关于此的信息吗?我什么也找不到。

我在做什么:我编写了一个工具来解释 mtrace() 生成的日志,找到可能的内存泄漏,并将它们追溯到分配数据的代码。对于后一步,我从日志中获取指令指针,在 /proc/pid/maps 的运行时映射中查找它以找到有问题的可执行文件或库,并使用它们的 nm-map 来查找实际函数做分配。

这对除可执行文件本身之外的所有内容都具有吸引力。

4

1 回答 1

2

/proc/$PID/maps 中的每一行都描述了进程或线程中的一个连续虚拟内存区域。每行都有以下字段:

address           perms offset  dev   inode   pathname
08048000-08056000 r-xp 00000000 03:0c 64593   /usr/sbin/gpm
  • 地址- 这是该区域在进程地址空间中的起始和结束地址
  • 权限- 这描述了如何访问区域中的页面。有四种不同的权限:读、写、执行和共享。如果读/写/执行被禁用,将出现一个“-”而不是“r”/“w”/“x”。如果一个区域不是共享的,它是私有的,所以会出现一个“p”而不是一个“s”。如果进程试图以不允许的方式访问内存,则会产生分段错误。可以使用 mprotect 系统调用更改权限。
  • offset - 如果该区域是从文件映射的(使用 mmap),则这是映射开始的文件中的偏移量。如果内存不是从文件映射的,则它只是 0。
  • device - 如果区域是从文件映射的,则这是文件所在的主要和次要设备号(十六进制)。
  • inode - 如果该区域是从文件映射的,则这是文件编号。
  • pathname - 如果区域是从文件映射的,则这是文件的名称。对于匿名映射区域,此字段为空白。还有一些特殊区域的名称如 [heap]、[stack] 或 [vdso]。[vdso] 代表虚拟动态共享对象。系统调用使用它来切换到内核模式。这是一篇关于它的好文章。

您可能会注意到很多匿名区域。这些通常由 mmap 创建,但不附加到任何文件。它们用于许多杂项,例如未在堆上分配的共享内存或缓冲区。例如,我认为 pthread 库使用匿名映射区域作为新线程的堆栈。

于 2015-06-02T10:09:23.820 回答