如何在C中查看Linux内存映射信息?

时间:2011-11-09 01:40:15

标签: c linux memory ld dlopen

我在C中动态加载一些Linux库。 我可以使用

获取库的起始地址
  

dlinfo

(见1)。

但是,我无法找到任何信息来获得图书馆的大小。

我发现的唯一一件事就是必须阅读

  

/ proc / [pid] / maps

文件并解析它以获取相关信息(请参阅2)。 有更优雅的方法吗?

2 个答案:

答案 0 :(得分:0)

(这个答案是LINUX / GLIBC特定的)

根据http://s.eresi-project.org/inc/articles/elf-rtld.txt

有link_map * map; map-> l_map_start& MAP-> l_map_end

    /* 
        ** Start and finish of memory map for this object.  
    ** l_map_start need not be the same as l_addr.  
    */
    ElfW(Addr) l_map_start, l_map_end;

有点不精确,如http://www.cygwin.com/ml/libc-hacker/2007-06/msg00014.html所述 =有些图书馆在记忆中没有连续;链接的字母有一些例子......例如这是检测的内部(to rtld)函数是否是lib的地址空间内的给定地址,基于link_map并直接使用ELF段:

/* Return non-zero if ADDR lies within one of L's segments.  */
int
internal_function
_dl_addr_inside_object (struct link_map *l, const ElfW(Addr) addr)
{
  int n = l->l_phnum;
  const ElfW(Addr) reladdr = addr - l->l_addr;

  while (--n >= 0)
    if (l->l_phdr[n].p_type == PT_LOAD
    && reladdr - l->l_phdr[n].p_vaddr >= 0
    && reladdr - l->l_phdr[n].p_vaddr < l->l_phdr[n].p_memsz)
      return 1;
  return 0;
}

这个函数是另一种选择,它可以找到加载的ELF的程序头/或节头(在link_map中有一些指向这些信息的链接)

最简单的方法是使用一些stat系统调用与map->l_name - 从磁盘读取文件大小(检测巨大的bss部分时不准确)。

答案 1 :(得分:0)

解析/proc/self/maps(或者popen - pmap命令 - 似乎对我来说仍然是最简单的事情。还有dladdr功能(前提是你有一些地址)。