Linux文件映射的查看方法有哪些

2024年 1月 21日 120.7k 0

一.文件映射的定义

文件映射是一种将磁盘上的文件映射到进程的虚拟内存空间的机制。

通过这种方式,进程可以直接通过内存地址来读写文件,而不必通过常规的 read 和 write 等系统调用。

我的理解:所谓的文件映射就是,创建一个文件,然后通过Linux提供的文件映射机制,将这个文件和进程的虚拟内存空间的一块内存绑定起来,然后对这个内存进行读写操作,就是对实际磁盘上文件的读写操作。

文件映射也可称内存映射,通常情况下这是一回事,内存映射包括将文件映射到内存的操作,也包括将匿名内存(不与文件关联的内存)映射到进程的地址空间的操作。

文件映射是内存映射的一种特例。

二.文件映射的查看方法【两种方法】

方法一:使用pmap工具

查看对应进程的文件映射信息

$ pmap -X 12345  #查看指定PID的文件映射信息
12345:   ./example
0000555555554000    100K r-x-- example
0000555555673000      4K r---- example
0000555555674000      4K rw--- example
00007ffff7de0000   1360K r-x-- libc-2.31.so
...
mapped: 1448K    writeable/private: 8K    shared: 0K
  • 每行代表一个内存映射区域。
  • 地址范围、权限、映射类型、文件路径等信息。
  • “mapped” 表示映射的总大小,”writeable/private” 表示可写和私有的大小,”shared” 表示共享的大小。

方法二:cat查看文件映射文件

使用 cat /proc/PID/maps 命令可以查看进程的内存映射情况。

每一行都表示一个内存映射区域,格式如下:

address           perms offset  dev   inode      pathname
00400000-0040b000 r-xp 00000000 08:01 1167685    /usr/bin/cat
0060a000-0060b000 r--p 0000a000 08:01 1167685    /usr/bin/cat
0060b000-0060c000 rw-p 0000b000 08:01 1167685    /usr/bin/cat
  • address: 映射的虚拟内存地址范围。
  • perms: 权限,包括读(r)、写(w)、执行(x)等。
  • offset: 文件中映射区域的偏移量。
  • dev: 设备号。
  • inode: 文件在文件系统中的节点号。
  • pathname: 映射的文件路径或匿名映射。

三. 如何在Linux下使用文件映射

现在我们通过一个例子演示了如何使用文件映射将文件映射到内存中,然后通过修改内存中的内容,最后通过解除内存映射来进行演示。

图片[1]-Linux文件映射的查看方法有哪些-不念博客

example.c文件

#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>

int main() {
    const char *file_path = "example.txt";
    const size_t file_size = 4096;

    int fd = open(file_path, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);
    if (fd == -1) {
        perror("open");
        exit(EXIT_FAILURE);
    }

    if (ftruncate(fd, file_size) == -1) {
        perror("ftruncate");
        close(fd);
        exit(EXIT_FAILURE);
    }

    // Create a memory-mapped region
    void *addr = mmap(NULL, file_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
    if (addr == MAP_FAILED) {
        perror("mmap");
        close(fd);
        exit(EXIT_FAILURE);
    }

    // Now 'addr' points to the beginning of the file in memory
    // 现在addr表示文件在进程的内存空间代表区域的起始位置
    // Write a message to the memory-mapped file
    // 向映射文件写入一句消息。
    const char *message = "Hello, Memory Mapping!n";
    strncpy(addr, message, strlen(message));

    printf("Press Enter to exit...n");
    getchar();  // Wait for user to press Enter

    // Unmap the memory region  解除文件和内存区域的映射关系
    if (munmap(addr, file_size) == -1) {
        perror("munmap");
        close(fd);
        exit(EXIT_FAILURE);
    }

    // Close the file descriptor
    close(fd);

    return 0;
}

编译执行:

$ ls
example.c
$ gcc example.c -o example
$ ./example
Press Enter to exit...

查看进程的文件映射信息:

$ ps aux|grep example
codersong   1524542  0.0  0.0   2776  1152 pts/0    S+   19:23   0:00 ./example
codersong   1524547  0.0  0.0  12188  2432 pts/2    S+   19:23   0:00 grep --color=auto example
$ pmap -X 1524542
1524542:   ./example
          地址 Perm 偏移量 设备   Inode Size  Rss Pss Pss_Dirty Referenced Anonymous LazyFree ShmemPmdMapped FilePmdMapped Shared_Hugetlb Private_Hugetlb Swap SwapPss Locked THPeligible Mapping
    557b482c3000 r--p  00000000  08:03 7124051    4    4   4         0          4         0        0              0             0              0               0    0       0      0           0 example
    557b482c4000 r-xp  00001000  08:03 7124051    4    4   4         0          4         0        0              0             0              0               0    0       0      0           0 example
    557b482c5000 r--p  00002000  08:03 7124051    4    4   4         0          4         0        0              0             0              0               0    0       0      0           0 example
    557b482c6000 r--p  00002000  08:03 7124051    4    4   4         4          4         4        0              0             0              0               0    0       0      0           0 example
    557b482c7000 rw-p  00003000  08:03 7124051    4    4   4         4          4         4        0              0             0              0               0    0       0      0           0 example
    557b48e9e000 rw-p  00000000  00:00       0  132    4   4         4          4         4        0              0             0              0               0    0       0      0           0 [heap]
    7f8fe5600000 r--p  00000000  08:03  264612  160  160   7         0        160         0        0              0             0              0               0    0       0      0           0 libc.so.6
    7f8fe5628000 r-xp  00028000  08:03  264612 1620  788  24         0        788         0        0              0             0              0               0    0       0      0           0 libc.so.6
    7f8fe57bd000 r--p  001bd000  08:03  264612  352   64   1         0         64         0        0              0             0              0               0    0       0      0           0 libc.so.6
    7f8fe5815000 r--p  00214000  08:03  264612   16   16  16        16         16        16        0              0             0              0               0    0       0      0           0 libc.so.6
    7f8fe5819000 rw-p  00218000  08:03  264612    8    8   8         8          8         8        0              0             0              0               0    0       0      0           0 libc.so.6
    7f8fe581b000 rw-p  00000000  00:00       0   52   20  20        20         20        20        0              0             0              0               0    0       0      0           0
    7f8fe58f6000 rw-p  00000000  00:00       0   12    8   8         8          8         8        0              0             0              0               0    0       0      0           0
    7f8fe5908000 rw-p  00000000  00:00       0    8    4   4         4          4         4        0              0             0              0               0    0       0      0           0
    7f8fe590a000 r--p  00000000  08:03  264600    8    8   0         0          8         0        0              0             0              0               0    0       0      0           0 ld-linux-x86-64.so.2
    7f8fe590c000 r-xp  00002000  08:03  264600  168  168   7         0        168         0        0              0             0              0               0    0       0      0           0 ld-linux-x86-64.so.2
    7f8fe5936000 r--p  0002c000  08:03  264600   44   40   1         0         40         0        0              0             0              0               0    0       0      0           0 ld-linux-x86-64.so.2
    7f8fe5941000 rw-s  00000000  08:03 7124052    4    4   4         0          4         0        0              0             0              0               0    0       0      0           0 example.txt
    7f8fe5942000 r--p  00037000  08:03  264600    8    8   8         8          8         8        0              0             0              0               0    0       0      0           0 ld-linux-x86-64.so.2
    7f8fe5944000 rw-p  00039000  08:03  264600    8    8   8         8          8         8        0              0             0              0               0    0       0      0           0 ld-linux-x86-64.so.2
    7ffef93f2000 rw-p  00000000  00:00       0  132   12  12        12         12        12        0              0             0              0               0    0       0      0           0 [stack]
    7ffef9485000 r--p  00000000  00:00       0   16    0   0         0          0         0        0              0             0              0               0    0       0      0           0 [vvar]
    7ffef9489000 r-xp  00000000  00:00       0    8    4   0         0          4         0        0              0             0              0               0    0       0      0           0 [vdso]
ffffffffff600000 --xp  00000000  00:00       0    4    0   0         0          0         0        0              0             0              0               0    0       0      0           0 [vsyscall]
                                               ==== ==== === ========= ========== ========= ======== ============== ============= ============== =============== ==== ======= ====== ===========
                                               2780 1344 152        96       1344        96        0              0             0              0               0    0       0      0           0 KB
$
$
$ cat /proc/1524542/maps
557b482c3000-557b482c4000 r--p 00000000 08:03 7124051                    /home/codersong/zhengshihong/example
557b482c4000-557b482c5000 r-xp 00001000 08:03 7124051                    /home/codersong/zhengshihong/example
557b482c5000-557b482c6000 r--p 00002000 08:03 7124051                    /home/codersong/zhengshihong/example
557b482c6000-557b482c7000 r--p 00002000 08:03 7124051                    /home/codersong/zhengshihong/example
557b482c7000-557b482c8000 rw-p 00003000 08:03 7124051                    /home/codersong/zhengshihong/example
557b48e9e000-557b48ebf000 rw-p 00000000 00:00 0                          [heap]
7f8fe5600000-7f8fe5628000 r--p 00000000 08:03 264612                     /usr/lib/x86_64-linux-gnu/libc.so.6
7f8fe5628000-7f8fe57bd000 r-xp 00028000 08:03 264612                     /usr/lib/x86_64-linux-gnu/libc.so.6
7f8fe57bd000-7f8fe5815000 r--p 001bd000 08:03 264612                     /usr/lib/x86_64-linux-gnu/libc.so.6
7f8fe5815000-7f8fe5819000 r--p 00214000 08:03 264612                     /usr/lib/x86_64-linux-gnu/libc.so.6
7f8fe5819000-7f8fe581b000 rw-p 00218000 08:03 264612                     /usr/lib/x86_64-linux-gnu/libc.so.6
7f8fe581b000-7f8fe5828000 rw-p 00000000 00:00 0
7f8fe58f6000-7f8fe58f9000 rw-p 00000000 00:00 0
7f8fe5908000-7f8fe590a000 rw-p 00000000 00:00 0
7f8fe590a000-7f8fe590c000 r--p 00000000 08:03 264600                     /usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2
7f8fe590c000-7f8fe5936000 r-xp 00002000 08:03 264600                     /usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2
7f8fe5936000-7f8fe5941000 r--p 0002c000 08:03 264600                     /usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2
7f8fe5941000-7f8fe5942000 rw-s 00000000 08:03 7124052                    /home/byzoro/zhengshihong/example.txt
7f8fe5942000-7f8fe5944000 r--p 00037000 08:03 264600                     /usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2
7f8fe5944000-7f8fe5946000 rw-p 00039000 08:03 264600                     /usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2
7ffef93f2000-7ffef9413000 rw-p 00000000 00:00 0                          [stack]
7ffef9485000-7ffef9489000 r--p 00000000 00:00 0                          [vvar]
7ffef9489000-7ffef948b000 r-xp 00000000 00:00 0                          [vdso]
ffffffffff600000-ffffffffff601000 --xp 00000000 00:00 0                  [vsyscall]

现在按ctrl+C退出example程序,查看example.txt文件的内容:

$ cat example.txt
Hello, Memory Mapping!

相关文章

服务器端口转发,带你了解服务器端口转发
服务器开放端口,服务器开放端口的步骤
产品推荐:7月受欢迎AI容器镜像来了,有Qwen系列大模型镜像
如何使用 WinGet 下载 Microsoft Store 应用
百度搜索:蓝易云 – 熟悉ubuntu apt-get命令详解
百度搜索:蓝易云 – 域名解析成功但ping不通解决方案

发布评论