[英]Reading /proc/pid/mem file returns nothing
I want to catch the memory mapping of current process to a file by reading the content of /proc/pid/mem
and writing it to another file.我想通过读取/proc/pid/mem
并将其写入另一个文件来捕获当前进程到文件的内存映射。 But the resulting file is empty every time.但是每次生成的文件都是空的。 I use sudo
, so I have no permission errors.我使用sudo
,所以我没有权限错误。 When I change the input file to some testing file, like "test_file_1.txt"
, all works as expected.当我将输入文件更改为某个测试文件时,例如"test_file_1.txt"
,一切都按预期工作。 What I do wrong?我做错了什么?
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
int main(int argc, char *argv[], char *envp[]) {
char filename[100];
pid_t pid = getpid();
printf("pid: %i\n", pid);
////It works with an usual file
// FILE *in_file = fopen("test_file_1.txt", "r");
////But doesn't work with this:
sprintf(filename, "/proc/%i/mem", pid);
FILE *in_file = fopen(filename, "r");
if(!in_file){
puts("in_file can't be opened");
}
sprintf(filename, "mem_%i.txt", pid);
FILE *out_file = fopen(filename, "w");
if(!out_file){
puts("out_file can't be opened");
}
char line[500];
while(fgets(line, 500, in_file)) {
fputs(line, out_file);
}
fclose(in_file);
fclose(out_file);
return 0;
}
Instead of proc/<pid>/mem
, you should use process_vm_readv(2)
.您应该使用process_vm_readv(2)
而不是proc/<pid>/mem
。
Really.真的。
/proc/<pid>/mem
is a legacy interface, which is still cute to use with dd
from the shell ("everything is a file", etc), but it makes no point to bother with it from C. /proc/<pid>/mem
是一个遗留接口,它在 shell 中与dd
一起使用仍然很可爱(“一切都是文件”等),但是从 C 中打扰它没有意义。
/proc/PID/mem
gives access to the memory of the process as it is mapped in the process: accessing the N th byte of this file is equivalent to accessing (*unsigned char) N
inside the process in C, or ptrace(PTRACE_PEEKDATA, PID , (void*) N , NULL)
from another process (or PTRACE_POKEDATA
for writing, and with the difference that ptrace
accesses one word at a time, not one byte at a time). /proc/PID/mem
允许访问在进程中映射的进程的内存:访问此文件的第N个字节相当于在 C 中访问进程内的(*unsigned char) N
,或ptrace(PTRACE_PEEKDATA, PID , (void*) N , NULL)
来自另一个进程(或PTRACE_POKEDATA
用于写入,区别在于ptrace
访问一个单词,而不是一次访问一个字节)。
Processes usually have nothing mapped at address 0. When you open the file and start reading, you're reading from address 0. Since there's nothing there, the read
call returns EIO
.进程通常在地址 0 没有任何映射。当您打开文件并开始读取时,您正在从地址 0 读取。由于那里没有任何内容,因此read
调用返回EIO
。 Use perror
to get more information about the failure of fgets
.使用perror
获取有关fgets
失败的更多信息。
Note that fgets
won't let you read from /proc/PID/mem
because it contains binary data, but fgets
only works on text (strings that don't contain null bytes).请注意, fgets
不会让您从/proc/PID/mem
读取,因为它包含二进制数据,但fgets
仅适用于文本(不包含空字节的字符串)。 Use open
, lseek
and read
to read from /proc/PID/mem
.使用open
、 lseek
和read
从/proc/PID/mem
读取。
Before reading from /proc/PID/mem
, you need to figure out where the process has things mapped.在从/proc/PID/mem
读取之前,您需要弄清楚进程的映射位置。 This information is in /proc/PID/maps
.此信息位于/proc/PID/maps
。 This file is in a text file with reasonable line lengths, so using fopen
and fgets
is fine.此文件位于具有合理fopen
的文本文件中,因此使用fopen
和fgets
。
If you're accessing the process's own memory, you can use /proc/self/…
instead of interpolating the PID.如果您正在访问进程自己的内存,则可以使用/proc/self/…
而不是插入 PID。
FILE *maps_file = fopen("/proc/self/maps", "r");
if (maps_file == NULL) {perror("/proc/self/maps"); exit(EXIT_FAILURE);}
char line[500];
while (fgets(line, sizeof(line), maps_file)) { ... }
fclose(maps_file);
尝试查看/proc/pid/maps
以查看该文件是否具有您要查找的内存映射信息。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.