Home / Alt manpages / proc_pid_map_files(5)

  • proc_pid_map_files(5)
  • File format
  • linux

List a Process's Mapped Files via /proc/pid/map_files

/proc/<pid>/map_files turns a process's memory mappings into a directory of symbolic links you can resolve straight back to real file paths. It is read-only: nothing here pauses, traces or reconfigures the process. Allow about five minutes for a first check. The examples use the shell's own process, so they are safe to repeat on a machine where you have an ordinary login.

1. Check the local documentation and kernel

The behaviour described here is from the installed proc_pid_map_files(5) page in Linux man-pages 6.7, supplied by the Debian package manpages 6.7-2. The running test host has Linux 6.8.0-139-generic. This matters, because the directory and its permission rules have changed across kernel releases.

$ man 5 proc_pid_map_files
PROC_PID_MAP_FILES(5)       Linux Programmer's Manual       PROC_PID_MAP_FILES(5)
$ uname -r
6.8.0-139-generic
$ dpkg-query -W -f='${Package} ${Version}\n' manpages
manpages 6.7-2

Do not treat the sample address values in a manual page as stable. Address space layout randomisation means the hexadecimal ranges will normally differ on every process start.

Checkpoint

You know which kernel and man-pages package you are testing. Continue with the installed command's output, not with copied addresses from documentation.

2. List the mapping entries for a process

Replace PID with a process ID you are allowed to inspect. Directory entries are named as start-end, both hexadecimal virtual addresses. Each entry is a memory region mapped from a file. A normal unprivileged process can usually inspect its own entries.

$ PID=$$
$ ls -l "/proc/$PID/map_files/" | head
lr-------- 1 alice alice 64 Sep 26 14:01 55b8f1a3c000-55b8f1a4c000 -> /usr/bin/bash
lr-------- 1 alice alice 64 Sep 26 14:01 55b8f1a4c000-55b8f1a5f000 -> /usr/bin/bash
lr-------- 1 alice alice 64 Sep 26 14:01 7f2b8c000000-7f2b8c021000 -> /usr/lib/x86_64-linux-gnu/libc.so.6

The owner, timestamp and addresses are host-specific. The useful part is the link target on the right; you may also see shared libraries, locale data and other files. This directory is not a replacement for /proc/<pid>/maps: maps gives the complete ranges and permissions, while map_files gives a link only for mappings that have a file identity.

Do not infer that every mapping is an ordinary application file. Linux implements some anonymous shared memory using the same machinery, so an entry can point at /dev/zero, sometimes followed by (deleted).

For a script or a quick investigation, select one entry and pass its exact path to readlink. This keeps the process ID and directory tied together, then prints the first entry found:

$ PID=$$
$ ENTRY=$(find "/proc/$PID/map_files" -mindepth 1 -maxdepth 1 -type l -print -quit)
$ printf 'mapping: %s\n' "$ENTRY"
mapping: /proc/18420/map_files/55b8f1a3c000-55b8f1a4c000
$ readlink "$ENTRY"
/usr/bin/bash

The example PID and address range are illustrative. On your machine the selected target can be a loader, a library or another mapped file. An empty ENTRY means no link was selected, not that the process has no memory mappings. Check /proc/$PID/maps if you need the full picture.

4. Inspect another process only when access permits

Reading another process's mapping links is controlled by a ptrace access check using PTRACE_MODE_READ_FSCREDS. The check considers both the reading and target process credentials, so seeing a PID in /proc does not guarantee its mapping links can be read.

$ PID=12345
$ ls -l "/proc/$PID/map_files/"
ls: cannot open directory '/proc/12345/map_files/': Permission denied

That failure is a permission boundary, not a reason to add sudo blindly. Confirm first that the PID still exists and belongs to the process you intend to inspect:

$ test -d "/proc/$PID" && tr '\0' ' ' < "/proc/$PID/cmdline"; printf '\n'
$ ps -p "$PID" -o pid=,user=,comm=
 12345 service  worker

Warning

If the process exited between commands, its /proc directory can disappear and the error will change. If access is genuinely required, use the host's approved administrative procedure and record why. Reading the links can disclose executable paths, library versions, deleted temporary files and other operational details, so treat the output as sensitive diagnostic data.

5. Understand capability changes across kernels

The installed manual records a second access rule for reading the link contents. Before Linux 5.9, the reading process needed CAP_SYS_ADMIN in the initial user namespace. Since Linux 5.9, it needs either CAP_SYS_ADMIN or CAP_CHECKPOINT_RESTORE there. This is separate from the ptrace access check, so satisfying one condition does not automatically satisfy the other.

For a quick capability check, inspect the current process without changing anything:

$ grep '^CapEff:' /proc/self/status
CapEff: 0000000000000000

The hexadecimal value is a bitmask, not a list of names. Do not edit it or use a capability-granting wrapper merely to make an experiment pass. If an inspection tool needs elevated access, run it only against a confirmed PID, capture the result you need, and close the privileged shell afterwards.

6. Handle disappearing and deleted mappings

Processes change while you inspect them. A mapping can vanish between ls and readlink, and a mapped file can be unlinked while the process keeps its mapping. In that case the target commonly ends with (deleted), which describes the name in the filesystem, not necessarily a broken mapping.

$ PID=$$
$ for entry in "/proc/$PID/map_files"/*; do
>   test -L "$entry" || continue
>   target=$(readlink "$entry") || continue
>   printf '%s -> %s\n' "${entry##*/}" "$target"
> done | head -5
55b8f1a3c000-55b8f1a4c000 -> /usr/bin/bash
55b8f1a4c000-55b8f1a5f000 -> /usr/bin/bash

The loop deliberately skips entries that disappear or cannot be resolved. Repeat the check if you need a current snapshot. Do not remove a target, kill a process or delete a file based only on this listing.

Done means

  • Checked the installed man-page and kernel versions.
  • Listed /proc/<pid>/map_files/ for a confirmed process.
  • Read the hexadecimal address range and resolved a link target.
  • Told apart the ptrace access check from the kernel capability rule.
  • Expected entries and targets to change while the process runs.
  • Made no persistent change to the process, filesystem or system configuration.