是否可以将为进程分配的当前内存(通过PID)转储到文件中?还是以某种方式阅读?

评论

您可以使用我的概念验证脚本读取/ proc / $ pid / mem。

您可能还想阅读superuser.com/questions/236390/…并改用gcore。

#1 楼

我不确定如何将所有内存转储到文件中而无需重复执行此操作(如果有人知道让gdb执行此操作的自动方法,请让我知道),但是以下假设适用于任何一批内存,前提是您知道pid:

$ cat /proc/[pid]/maps


这将是以下格式(示例):

00400000-00421000 r-xp 00000000 08:01 592398                             /usr/libexec/dovecot/pop3-login
00621000-00622000 rw-p 00021000 08:01 592398                             /usr/libexec/dovecot/pop3-login
00622000-0066a000 rw-p 00622000 00:00 0                                  [heap]
3e73200000-3e7321c000 r-xp 00000000 08:01 229378                         /lib64/ld-2.5.so
3e7341b000-3e7341c000 r--p 0001b000 08:01 229378                         /lib64/ld-2.5.so


挑选一批内存(例如00621000-00622000),然后将gdb用作root附加到进程并转储该内存:

$ gdb --pid [pid]
(gdb) dump memory /root/output 0x00621000 0x00622000


然后使用字符串命令,减少了整个屏幕上都需要腻子的情况。

评论


有没有办法在没有gdb的bash / sh中做到这一点?

–Programming4life
17-3-25在5:35



@ Programming4life gcore(1)

–朱利安
17年4月22日在12:59

#2 楼

我制作了一个脚本来完成此任务。

这个想法来自詹姆斯·劳里(James Lawrie)的回答以及这篇文章:http://www.linuxforums.org/forum/programming-scripting/52375-reading- memory-other-processes.html#post287195

#!/bin/bash

grep rw-p /proc//maps \
| sed -n 's/^\([0-9a-f]*\)-\([0-9a-f]*\) .*$/ /p' \
| while read start stop; do \
    gdb --batch --pid  -ex \
        "dump memory -$start-$stop.dump 0x$start 0x$stop"; \
done


将其放入文件中(例如,“ dump-all-memory-of-pid.sh”)并制作它可执行文件

用法:./dump-all-memory-of-pid.sh [pid]

输出将打印到名称为:pid-startaddress-stopaddress.dump

相关性:gdb
的文件

评论


太棒了!只是使用它来发现神秘的bash实例正在运行哪个脚本。

– Tobia
16年7月26日在17:02

为什么只使用rw-p权限来查找和丢弃范围?

–mxmlnkn
19年8月4日在18:45

@mxmlnkn这是数据(rw-p),其他范围用于代码(r-xp)。如果您都希望两者都转储,请继续将grep换成例如猫。

– A. Nilsson
19年8月5日在14:55

#3 楼

请尝试

    gcore $pid


其中$pid是pid的实际编号;有关更多信息,请参见:info gcore

可能需要一些时间来进行转储,并且某些内存可能不可读,但是足够好...请注意它可以创建大文件,我刚刚以这种方式创建了2GB的文件。

评论


gcore正在转储稀疏文件吗?

– CMCDragonkai
16年7月30日在7:02

@CMCDragonkai使用gcore -a PID

– e2-e4
20年5月21日在5:30

#4 楼

纯bash解决方案:

 procdump() 
( 
    cat /proc//maps | grep "rw-p" | awk '{print }' | ( IFS="-"
    while read a b; do
        dd if=/proc//mem bs=$( getconf PAGESIZE ) iflag=skip_bytes,count_bytes \
           skip=$(( 0x$a )) count=$(( 0x$b - 0x$a )) of="_mem_$a.bin"
    done )
)
 


用法:procdump PID

为更干净的转储筛选出*.so内存映射的共享库和空内存范围:

 procdump()
( 
    cat /proc//maps | grep -Fv ".so" | grep " 0 " | awk '{print }' | ( IFS="-"
    while read a b; do
        dd if=/proc//mem bs=$( getconf PAGESIZE ) iflag=skip_bytes,count_bytes \
           skip=$(( 0x$a )) count=$(( 0x$b - 0x$a )) of="_mem_$a.bin"
    done )
)
 


评论


因此,据我所知,更干净的转储背后的想法是,与实际应用程序内存相比,只有内存文件具有附加到内存区域的大小,而实际应用程序内存的大小为0(因为实际使用的大小是未知的操作系统)。

–mxmlnkn
19年8月4日在19:04

我使用此脚本的一个问题是,与使用等于页面大小(对于我而言为4096)的块大小(相比于我获得〜100MB / s)的块大小相比,块大小为1导致的带宽缓慢到〜30kB / s!看这里。 getconf PAGESIZE用于获取页面大小,然后将地址和计数除以它。

–mxmlnkn
19年8月4日在19:30

懒惰的@mxmlnkn,随时纠正我的答案。

– Zibri
20 Mar 6 '20 at 0:06

好的,我会做。还要注意,计数计算是错误的,因为它是使用bd-ad完成的,但是bd和ad仅在之后的第一个bash代码段中计算。

–mxmlnkn
20 Mar 6 '20 at 12:03

#5 楼

man proc说:


/ proc / [pid] / mem
该文件可用于通过open(2)访问进程的内存页,read(2)和lseek(2)。


也许可以帮助您

评论


这还不够,读取另一个进程需要/ proc / / {mem,* maps},ptrace和一些信号处理的组合,以避免挂起目标进程。

–东武
13年3月19日在10:57

@东武确实。我写了一个概念证明脚本。

–吉尔斯'所以-不再是邪恶的'
2014年1月15日上午9:18

#6 楼

我也编写了自己的程序来转储整个进程的内存,它在C语言中,因此可以交叉编译到Android,这是我所需要的。 。源代码在这里。

#7 楼

将过程转储到标准输出的工具pcat / memdump:


http://manpages.ubuntu.com/manpages/gutsy/man1/pcat.1.html
http ://www.porcupine.org/forensics/tct.html


评论


该版本已过时(应维护者的要求删除);我仍然安装了旧软件包,但失败并显示“输入/输出错误;您是否将GCC与另一台计算机的头文件一起使用?”。

–东武
13年3月19日在11:14

#8 楼

现在,您可以在Linux上的SysInternals套件中使用procdump:

https://github.com/Microsoft/ProcDump-for-Linux

#9 楼

如果要转储正在运行的进程的单独的内存段而不创建巨大的核心文件(例如使用gcore),则可以从此处使用一个小工具。
如果您希望将所有可读段都转储到单独的文件中,则README中也有一种语言。