使用C用户空间代码从Linux / proc接口读取的最佳方法是什么?

时间:2012-03-19 03:27:05

标签: c linux memory memory-management linux-kernel

根据man 5 proc,可以使用/proc文件系统访问Linux上的以下信息:

   /proc/[pid]/maps
          A file containing the currently mapped memory regions and their access
          permissions.

          The format is:

          address           perms offset  dev   inode   pathname
          08048000-08056000 r-xp 00000000 03:0c 64593   /usr/sbin/gpm
          08056000-08058000 rw-p 0000d000 03:0c 64593   /usr/sbin/gpm
          08058000-0805b000 rwxp 00000000 00:00 0
          40000000-40013000 r-xp 00000000 03:0c 4165    /lib/ld-2.2.4.so
          40013000-40015000 rw-p 00012000 03:0c 4165    /lib/ld-2.2.4.so
          4001f000-40135000 r-xp 00000000 03:0c 45494   /lib/libc-2.2.4.so
          40135000-4013e000 rw-p 00115000 03:0c 45494   /lib/libc-2.2.4.so
          4013e000-40142000 rw-p 00000000 00:00 0
          bffff000-c0000000 rwxp 00000000 00:00 0

          where "address" is the address space in the process that it occupies,
          "perms" is a set of permissions:

               r = read
               w = write
               x = execute
               s = shared
               p = private (copy on write)

          "offset" is the offset into the file/whatever, "dev" is the device
          (major:minor), and "inode" is the inode on that device.  0 indicates
          that no inode is associated with the memory region, as the case would
          be with BSS (uninitialized data).

          Under Linux 2.0 there is no field giving pathname.

我真的不想在C中编写文本解析代码;我宁愿只是调用操作系统并直接将信息读入结构中。我查看/usr/include/linux以查看是否有明显的API结构,但没有看到任何内容。

所以,有两部分问题:

  1. 这可以被视为“坏主意”吗?也就是说,如果内核接口发生变化,用户程序是否应该咬住子弹并从/proc读取文本?如果是这样,使用C从/proc读取是否有可接受的“最佳做法”? (fscanf()?正则表达式?)
  2. 如何查找内核接口的文档(假设它们存在),这样我才能直接读取这些数据? (内核源代码本身是最好的起点吗?如果是这样,我应该在内核源代码中查找哪些内容?)如果您知道哪个接口可以专门提供/proc/[pid]/maps数据,则可以获得奖励积分。 =)

3 个答案:

答案 0 :(得分:8)

我认为对于perl或shell脚本,读取和解析/ proc / data非常好。在C程序中,如果需要健壮性,我会使用内核(可能是sysctl)接口。

事实证明procps-bundled pmap implementation逐行解析/proc/PID/maps个文件,如下所示(参见one_proc()函数):

sscanf(mapbuf,"%"KLF"x-%"KLF"x %31s %Lx %x:%x %Lu", &start, &end, flags, &file_offset, &dev_major, &dev_minor, &inode);

编辑:我的答案的原始版本显示了一种解析共享内存段数据的方法,而不是所有映射的内存段作为OP所需。

我相信ipcs -m会为您提供多个流程的相同数据。因此,您的第二个问题的答案是,您应该阅读ipcs代码:(例如BSD versionLinux version):

答案 1 :(得分:2)

顺序读取像/proc/self/maps这样的文本伪文件是在Linux上获取信息的规范方式(并且没有简单的方法来获取它;它是内核提供它的方式。)

您可以使用某些库(例如libproc)来为您执行此操作。但最终您的应用程序将在/proc下解析(可能通过一些库)文件。我不确定你是否应该避免这种情况。

尝试运行pstop之类的命令,并卸载/proc。它可能不再适用了。

答案 2 :(得分:1)

libproc提供了一种访问/proc下内容的便捷方式。