2月 142014
 

プロセスのコールスタックを調べるシェルスクリプト | Inhale n’ Exhale自分の知らないところで、あるコマンドが実行されているということはLinuxでは珍しいことではない。代表的なのはcronだ。ただ、cronならcrontab -lをしたり、直接/var/spool/cron/crontabs/*を調べれば、どんなコマンドが実行されるかすぐに調べがつく。しかし、あるイベントが発生したことをトリガーにしてコマンドが実行された場合、なぜそのコマンドが突然呼ばれたのかということに困惑することがある。

例えば、ifupコマンドが実行された場合、/etc/network/if-pre-up.d/etc/network/if-up.d配下にあるコマンドが、ifupの実行中に呼び出されるようになっている。あるコマンドが実行されていることはログなどからわかっているが、どのような経緯で実行されるに至ったかがわからない、という場合には、そのコマンドの親プロセスを辿っていけば調べることができる。


実行されているコマンドがバイナリだと手も足も出ないかもしれないが、シェルスクリプトであれば、以下のようなスクリプトを使って呼び出し元の親プロセスたちを辿ることができる。

trace_parents()
{
    local pid=$$ cmd
    while true; do
        cmd="$(cat /proc/$pid/cmdline | tr '\0' ' ')"
        echo -e "pid=$pid, cmd=$cmd"
        [ $pid -eq 1 ] && break
        pid=$(awk '/^PPid:/{print $2}' /proc/$pid/status)
    done
}

trace_parents > /tmp/parents.$(basename $0).log

PIDが1、すなわちinitになるまで/proc/pid/statusの中から親プロセスのPIDを辿っていくというものだ。/proc/pid/cmdlinecatでダンプさせると、コマンドライン引数の間にスペースがないように見えるが、区切り文字はnull文字(\0)になっているので、trでスペースに置換すれば見やすくなる。

 返信する

以下のHTML タグと属性が利用できます: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

(required)

(required)

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください