Capture input/output of a process with gdb

My tip of day. When you lose control of a process (for example with a process launched with disown or, another example, when you close your SSH terminal with “unsynced” mutt), thanks gdb.

$ tty
/dev/pts/13
$ gdb --pid=`pidof mutt`
(gdb) call close(0)
(gdb) call close(1)
(gdb) call close(2)
(gdb) call open("/dev/pts/13", 2, 0)
(gdb) call dup(0)
(gdb) call dup(0)
(gdb) detach
Detaching from program: /usr/bin/mutt-org, process 2932

Thanks to this comment on superuser.com for the original idea.

Edit: correction on dup() calls. Thanks to Peter Pentchev for his explanation in comments.

Tags: , , , ,

3 Responses to “Capture input/output of a process with gdb”

  1. Great tip! Just… is there really a need for the final dup(2) call? :) The way I’m reading it, open() would open the PTY at file descriptor 0, the first dup() would duplicate it to 1, the second dup() would also duplicate it to 2… and the dup(2) call would duplicate it once again to the next-lowest-numbered file descriptor.

    Actually, the dup(1) call might as well be written as dup(0), just as in the superuser.com original quote :)

    But yeah, thanks for the tip!

  2. Ken Bloom says:

    The dup2 system call would make it more clear which file descriptors are being changed.

  3. Ken Bloom says:

    A better approach using the dup2 system call would be

    call open(“/dev/pts/13”,2,0)
    (this returns an integer such as 3, which is the file descriptor of the file you just opened)
    call dup2(3,0)
    call dup2(3,1)
    call dup2(3,2)