8
9

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

プロセスを生かしたまま出力先を変更

Last updated at Posted at 2016-10-02

アプリのログを/dev/nullに流してしまった。すでに流れてしまったものは取り戻せないが、以降のログをなんとかプロセスを生かしたままファイルに出力させたいという場合はよくある。
gdbを使えばそれが可能となる。

追記:
書いた後ですでに同じような記事があるのを見つけてしまったが若干やり方が異なっていたりしたのでそのまま公開。

準備

1秒毎にHelloを出力するだけのプログラム。

hello.cpp
#include <iostream>
#include <unistd.h>

int main(int argc, char *argv[])
{
    while(true) {
        std::cout << "Hello" << std::endl;
        sleep(1);
    }
    return 0;
}
$ g++ -o hello hello.cpp
$ ./hello
Hello
Hello
...

gdbで出力先変更

標準出力を/dev/nullにリダイレクトしてみる

$ ./hello > /dev/null

プロセスが持つファイルディスクリプタ一覧の/proc/$(pidof hello)/fdを見ると確かに標準出力(1)が/dev/nullに向かっていることがわかる

$ ls -la /proc/$(pidof hello)/fd
合計 0
dr-x------ 2 maueki maueki  0 10月  2 15:26 .
dr-xr-xr-x 9 maueki maueki  0 10月  2 15:26 ..
lrwx------ 1 maueki maueki 64 10月  2 15:26 0 -> /dev/pts/4
l-wx------ 1 maueki maueki 64 10月  2 15:26 1 -> /dev/null
l-wx------ 1 maueki maueki 64 10月  2 15:26 2 -> /dev/pts/4

gdbを使って標準出力を/tmp/hello_logに流れるようにしてみる。

$ gdb
...
(gdb) shell pidof hello
25168
(gdb) attach 25168
Attaching to process 25168
...
(gdb) call open("/tmp/hello_log", 66, 0666)
$1 = 3
(gdb) call dup2($1, 1)
$2 = 1
(gdb) call close($1)
$3 = 0
(gdb) detach
Detaching from program: /tmp/hello, process 25168
(gdb) quit

これで出力先が変更された

$ cat /tmp/hello_log
Hello
Hello
...

/proc/$(pidof hello)/fdを見ても確かに変更されている

$ ls -la /proc/$(pidof hello)/fd
合計 0
dr-x------ 2 maueki maueki  0 10月  2 15:26 .
dr-xr-xr-x 9 maueki maueki  0 10月  2 15:26 ..
lrwx------ 1 maueki maueki 64 10月  2 15:26 0 -> /dev/pts/4
l-wx------ 1 maueki maueki 64 10月  2 15:26 1 -> /tmp/hello_log
l-wx------ 1 maueki maueki 64 10月  2 15:26 2 -> /dev/pts/4

解説

gdbのcallコマンドではCの関数が呼び出せる。

  1. まずopenで差し替え先ファイルを開く。引数の66はO_CREAT|O_RDWR。ファイルディスクリプタが$1に入る
  2. 次にdup2で$1を標準出力(1)として複製する
  3. 最後に$1をcloseして終わり

おわりに

今回は標準出力を差し替えたが基本的にどのファイルでも差し替えが可能。以下のサイトではプロセスが開いている任意のファイルを差し替えるスクリプトが公開されている。

8
9
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
9

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?