Kịch bản python nhanh và bẩn sau đây đưa bộ nhớ của một tiến trình vào thiết bị xuất chuẩn. Điều này có tác dụng phụ là tải bất kỳ trang bị hoán đổi hoặc tệp ánh xạ. Gọi nó là cat_proc_mem 123 456 789
nơi các đối số là ID quá trình.
Kịch bản này là hoàn toàn cụ thể cho Linux. Nó có thể thích ứng với các hệ thống khác có /proc
cấu trúc tương tự (Solaris?), Nhưng quên đi việc chạy nó trên ví dụ * BSD. Ngay cả trên Linux, bạn có thể cần thay đổi định nghĩa c_pid_t
và các giá trị của PTRACE_ATTACH
và PTRACE_DETACH
. Đây là một kịch bản chứng minh nguyên tắc, không có nghĩa là một ví dụ về thực hành lập trình tốt. Sử dụng có nguy cơ của riêng bạn.
Linux làm cho bộ nhớ của một quá trình có sẵn như /proc/$pid/mem
. Chỉ có phạm vi địa chỉ nhất định là có thể đọc được. Những phạm vi này có thể được tìm thấy bằng cách đọc thông tin ánh xạ bộ nhớ từ tệp văn bản /proc/$pid/maps
. Tệp giả /proc/$pid/mem
có thể được đọc bởi tất cả các quy trình có quyền đọc nó: quá trình đọc phải được gọi ptrace(PTRACE_ATTACH, $pid)
.
#!/usr/bin/env python
import ctypes, re, sys
## Partial interface to ptrace(2), only for PTRACE_ATTACH and PTRACE_DETACH.
c_ptrace = ctypes.CDLL("libc.so.6").ptrace
c_pid_t = ctypes.c_int32 # This assumes pid_t is int32_t
c_ptrace.argtypes = [ctypes.c_int, c_pid_t, ctypes.c_void_p, ctypes.c_void_p]
def ptrace(attach, pid):
op = ctypes.c_int(16 if attach else 17) #PTRACE_ATTACH or PTRACE_DETACH
c_pid = c_pid_t(pid)
null = ctypes.c_void_p()
err = c_ptrace(op, c_pid, null, null)
if err != 0: raise SysError, 'ptrace', err
## Parse a line in /proc/$pid/maps. Return the boundaries of the chunk
## the read permission character.
def maps_line_range(line):
m = re.match(r'([0-9A-Fa-f]+)-([0-9A-Fa-f]+) ([-r])', line)
return [int(m.group(1), 16), int(m.group(2), 16), m.group(3)]
## Dump the readable chunks of memory mapped by a process
def cat_proc_mem(pid):
## Apparently we need to ptrace(PTRACE_ATTACH, $pid) to read /proc/$pid/mem
ptrace(True, int(pid))
## Read the memory maps to see what address ranges are readable
maps_file = open("/proc/" + pid + "/maps", 'r')
ranges = map(maps_line_range, maps_file.readlines())
maps_file.close()
## Read the readable mapped ranges
mem_file = open("/proc/" + pid + "/mem", 'r', 0)
for r in ranges:
if r[2] == 'r':
mem_file.seek(r[0])
chunk = mem_file.read(r[1] - r[0])
print chunk,
mem_file.close()
## Cleanup
ptrace(False, int(pid))
if __name__ == "__main__":
for pid in sys.argv[1:]:
cat_proc_mem(pid)
Xem thêm thông tin về/proc/$pid/mem
.
unswap () {
cat_proc_mem "$@" >/dev/null
}
swapon
/swapoff
(như câu trả lời hiện được chấp nhận cho thấy), bạn có thể muốn hủy bỏ trình quản lý hiển thị của mình và tất cả các con của nó bằng cách bỏ các ký ức quá trình của chúng (bắt buộc bỏ qua). Xem thêm Cách làm thế nào để buộc một quá trình zsh hoán đổi để hoán đổi trong? Vượt trên stackoverflow.