GNU/Linux >> Znalost Linux >  >> Linux

Čtení živé paměti procesu bez přerušení

Od verze 3.2 jádra. Systémové volání process_vm_readv můžete použít ke čtení paměti procesu bez přerušení.

ssize_t process_vm_readv(pid_t pid,
                                const struct iovec *local_iov,
                                unsigned long liovcnt,
                                const struct iovec *remote_iov,
                                unsigned long riovcnt,
                                unsigned long flags);

Tato systémová volání přenášejí data mezi adresním prostorem volajícího procesu ("místní proces") a procesem identifikovaným bypid ("vzdálený proces"). Data se přesouvají přímo mezi adresními prostory dvou procesů, aniž by procházela prostorem jádra.


Pro proces 1234 můžete získat jeho paměťovou mapu postupným čtením /proc/1234/maps (textový pseudosoubor) a číst virtuální paměť např. read(2)-ing nebo mmap(2)-ing příslušných segmentů /proc/1234/mem řídký pseudosoubor.

Věřím však, že se nějakému druhu synchronizace nevyhnete (možná s ptrace(2), jako gdb dělá), protože proces 1234 může (a dělá) kdykoli změnit svůj adresní prostor (pomocí mmap a související systémová volání).

Situace je jiná, pokud monitorovaný proces 1234 není libovolný, ale pokud jej můžete vylepšit, aby nějak komunikoval s procesem monitorování.

Nejsem si jistý, že rozumím, proč se na to ptáte. A gdb je schopen watch nějaké místo bez zastavení procesu.


Pokud máte přístup root a používáte linuxový systém, můžete použít následující linuxový skript (upravený z vynikající Gillesovy odpovědi unix.stackexchange.com a odpovědi původně uvedené ve výše uvedené otázce, ale včetně SyntaxErrors a bez pythonic):

#!/usr/bin/env python

import re
import sys

def print_memory_of_pid(pid, only_writable=True):
    """ 
    Run as root, take an integer PID and return the contents of memory to STDOUT
    """
    memory_permissions = 'rw' if only_writable else 'r-'
    sys.stderr.write("PID = %d" % pid)
    with open("/proc/%d/maps" % pid, 'r') as maps_file:
        with open("/proc/%d/mem" % pid, 'r', 0) as mem_file:
            for line in maps_file.readlines():  # for each mapped region
                m = re.match(r'([0-9A-Fa-f]+)-([0-9A-Fa-f]+) ([-r][-w])', line)
                if m.group(3) == memory_permissions: 
                    sys.stderr.write("\nOK : \n" + line+"\n")
                    start = int(m.group(1), 16)
                    if start > 0xFFFFFFFFFFFF:
                        continue
                    end = int(m.group(2), 16)
                    sys.stderr.write( "start = " + str(start) + "\n")
                    mem_file.seek(start)  # seek to region start
                    chunk = mem_file.read(end - start)  # read region contents
                    print chunk,  # dump contents to standard output
                else:
                    sys.stderr.write("\nPASS : \n" + line+"\n")

if __name__ == '__main__': # Execute this code when run from the commandline.
    try:
        assert len(sys.argv) == 2, "Provide exactly 1 PID (process ID)"
        pid = int(sys.argv[1])
        print_memory_of_pid(pid)
    except (AssertionError, ValueError) as e:
        print "Please provide 1 PID as a commandline argument."
        print "You entered: %s" % ' '.join(sys.argv)
        raise e

Pokud to uložíte jako write_mem.py, můžete to spustit (s python2.6 nebo 2.7) nebo brzy v python2.5 (pokud přidáte from __future__ import with_statement ) jako:

sudo python write_mem.py 1234 > pid1234_memory_dump

pro výpis paměti pid1234 do souboru pid1234_memory_dump.


Linux
  1. Počítání otevřených souborů na proces

  2. -bash:fork:Nelze alokovat paměť

  3. Aktuální umask procesu s <pid>

  1. Špičkové využití paměti procesem

  2. Jak se v Linuxu hlásí využití paměti?

  3. Proměnné prostředí běžícího procesu na Unixu?

  1. Ruční vytváření kontejnerů:jmenný prostor PID

  2. Linux – Omezit využití paměti pro jeden linuxový proces?

  3. Jak získat PID právě zahájeného procesu