查看正在运行的进程的stdin/stdout/stderr - Linux内核

3

有没有简单的方法来重定向/查看正在运行的进程(按PID)的stdin/stdout/stderr?

我尝试了以下方法(假设'pid'包含一个运行中的用户进程):

int foo(const void* data, struct file* file, unsigned fd)
{
    printf("Fd = %x\n", fd);
    return 0;
}
struct task_struct* task = pid_task(find_vpid(pid), PIDTYPE_PID);
struct files_struct* fs = task->files;
iterate_fd(fs, 0, foo, NULL);

我收到了3个foo的调用(这个进程可能有3个打开的文件,这很合理),但我实际上无法从它们(从文件指针)中读取。

它会打印:

0
1
2

有没有比较简单的方法可以实现我所要求的内容呢?

谢谢。

2个回答

4

首先,如果您可以更改架构,建议在类似于 screen、tmux、nohup 或 dtach 的环境下运行程序,这样会使您的生活更加轻松。

但是如果您已经有一个正在运行的程序,可以使用 strace 监控其内核调用,包括所有读/写操作。您需要限制它看到的内容(尝试使用 -e),并可能仅过滤前3个文件描述符的输出。还要添加 -s,因为默认情况下会限制记录的数据大小。例如:strace -p <PID> -e read,write -s 1000000


3
您可以通过gdb实现这一点。
检查process()打开的文件句柄:
$ ls -l /proc/6760/fd
total 3
lrwx—— 1 rjc rjc 64 Feb 27 15:32 0 -> /dev/pts/5
l-wx—— 1 rjc rjc 64 Feb 27 15:32 1 -> /tmp/foo1
lrwx—— 1 rjc rjc 64 Feb 27 15:32 2 -> /dev/pts/5

现在运行GDB:
$ gdb -p 6760 /bin/cat
GNU gdb (Ubuntu 7.7.1-0ubuntu5~14.04.2) 7.7.1
Copyright (C) 2014 Free Software Foundation, Inc.
[lots more license stuff snipped]
Attaching to program: /bin/cat, process 6760
[snip other stuff that’s not interesting now]

(gdb) p close(1)
$1 = 0

提供一个新的文件名以获取输出 - process_log
(gdb) p creat(“/tmp/process_log″, 0600)
$2 = 1
(gdb) q
The program is running. Quit anyway (and detach it)? (y or n) y
Detaching from program: /bin/cat, process 6760

然后验证结果如下:

ls -l /proc/6760/fd/
total 3
lrwx—— 1 rjc rjc 64 2008-02-27 15:32 0 -> /dev/pts/5
l-wx—— 1 rjc rjc 64 2008-02-27 15:32 1 -> /tmp/process_log <====
lrwx—— 1 rjc rjc 64 2008-02-27 15:32 2 -> /dev/pts/5

同样的方法,您也可以重定向stdin和stderr。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接