How can I redirect an already running process's stdout/stderr?

Solution 1:

It looks like those instructions given for gdb are incorrect and incomplete in several ways.

First, you need to use

gdb [executablefile] [pid]

so that GDB knows what the program it's connecting to actually is. I just tested this, and it can use a stripped executable. Note that while gdb is attached to the process the process will be suspended. If this process is communicating over a network, type quickly or the network connection will probably timeout.

Second, the commands given don't explain what they're doing, and the instruction that you should cd "to a directory that you want your program to write files to" is wrong, since gdb is asking the original program to execute the creat() function. The example given will create myprog.stderr and myprog.stdout files in the Current Working Directory of the running program, not in the directory you ran gdb. Use absolute pathnames here if you don't know what that program's CWD is (or look at ls -l /proc/[pid]/cwd).

Third, running with the lack of explanation, it's important to know that the first parameter to dup2() is the file descriptor number returned by the previous creat() so if this running program had several files open you might end up with an exchange like

(gdb) call creat("/home/me/myprog.stdout",0600)
$1 = 7
(gdb) call dup2(7,1)
$2 = 1
(gdb) call creat("/home/me/myprog.stderr",0600)
$3 = 8
(gdb) call dup2(8,2)
$4 = 2

When you quit gdb, it'll ask you if you want to "quit anyway (and detach it)" the answer is yes.

Finally, bg and disown are bash builtins. If you weren't using bash, then you're on your own from here. bg moves a suspended job to the background as if it were started there using somecommand &, and disown removes the program from bash's list of active programs to SIGHUP when bash exits.