drgn/contrib/vmmap.py
Martin Liska 983ec87a77 contrib: add vmmap.py script
Mimics `cat /proc/$pid/maps` and the script output is:

Start        End          Flgs   Offset Dev   Inode            File path
55dee5284000-55dee53f3000 r-xp 00000000 fd:02 10515            /usr/lib/systemd/systemd
55dee53f3000-55dee5441000 r--p 0016f000 fd:02 10515            /usr/lib/systemd/systemd
55dee5441000-55dee5442000 rw-p 001bd000 fd:02 10515            /usr/lib/systemd/systemd
55dee5f4c000-55dee615d000 rw-p 00000000 00:00 0
7f5fc801c000-7f5fc8024000 r-xp 00000000 fd:02 1181379          /usr/lib64/libffi.so.7.1.0
7f5fc8024000-7f5fc8224000 ---p 00008000 fd:02 1181379          /usr/lib64/libffi.so.7.1.0
7f5fc8224000-7f5fc8225000 r--p 00008000 fd:02 1181379          /usr/lib64/libffi.so.7.1.0
...

Signed-off-by: Martin Liska <mliska@suse.cz>
Co-authored-by: Omar Sandoval <osandov@osandov.com>
2023-02-25 02:08:46 -08:00

58 lines
1.6 KiB
Python
Executable File

#!/usr/bin/env drgn
# Copyright (c) SUSE Linux.
# SPDX-License-Identifier: LGPL-2.1-or-later
"""Print memory map of a given task."""
import os
import sys
from drgn.helpers.linux.device import MAJOR, MINOR
from drgn.helpers.linux.fs import d_path
from drgn.helpers.linux.pid import find_task
if len(sys.argv) != 2:
sys.exit("Usage: ./vmmap.py PID")
pid = int(sys.argv[1])
task = find_task(prog, int(pid))
if not task:
sys.exit(f"Cannot find task {pid}")
try:
vma = task.mm.mmap
except AttributeError:
sys.exit('maple tree VMA mmap is not supported yet (v6.1+)')
FLAGS = ((0x1, "r"), (0x2, "w"), (0x4, "x"))
PAGE_SHIFT = prog["PAGE_SHIFT"]
print("Start End Flgs Offset Dev Inode File path")
# Starting with 763ecb035029f500d7e6d ("mm: remove the vma linked list") (in v6.1),
# the VMA mmap linked list is replaced with maple tree which is not supported right now:
# https://github.com/osandov/drgn/issues/261
while vma:
flags = "".join([v if f & vma.vm_flags else "-" for f, v in FLAGS])
flags += "s" if vma.vm_flags & 0x8 else "p"
print(f"{vma.vm_start.value_():0x}-{vma.vm_end.value_():0x} {flags} ",
end="")
vmfile = vma.vm_file
if vmfile:
inode = vmfile.f_inode.i_ino.value_()
dev = vmfile.f_inode.i_sb.s_dev
major, minor = MAJOR(dev), MINOR(dev)
path = os.fsdecode(d_path(vmfile.f_path))
pgoff = (vma.vm_pgoff << PAGE_SHIFT).value_()
else:
inode = 0
major, minor = 0, 0
path = ""
pgoff = 0
print(f"{pgoff:08x} {major:02x}:{minor:02x} {inode:<16} {path}")
vma = vma.vm_next