pidof の -S / --separtor オプション で複数プロセスに strace する

procps の ML を眺めていたら便利そうな新機能がマージされていた

gitlab.com

$ ./pidof -h

Usage:
 lt-pidof [options] [program [...]]

Options:
 -s, --single-shot         return one PID only
 -c, --check-root          omit processes with different root
 -x                        also find shells running the named scripts
 -o, --omit-pid <PID,...>  omit processes with PID
 -S, --separator SEP       use SEP as separator put between PIDs 👈
 -h, --help     display this help and exit
 -V, --version  output version information and exit

For more details see pidof(1).

誰に便利って、頻繁に strace 使う人向け (コミットの説明にもまんま例が書いてある)

I frequency use pidof command with strace system call tracer.
strace can trace MULTIPLE processes specified with "-p $PID"
arguments like:

      strace -p 1 -p 1030 -p 3043

Sometimes I want to do as following

      strace -p $(pidof httpd)

However, above command line doesn't work because -p option
is needed for specifying a pid. pidof uses a whitespace as
a separator. For passing the output to strace, the separator
should be replaced with ' -p '.

This maybe not a special to my use case.

This commit introduces -S option that allows a user to specify a
separator the one wants.

    $ ./pidof bash
    ./pidof bash
    24624 18790 12786 11898 11546 10766 7654 5095
    $ ./pidof -S ',' bash
    ./pidof -S ',' bash
    24624,18790,12786,11898,11546,10766,7654,5095
    $ ./pidof -S '-p ' bash
    ./pidof -S '-p ' bash
    24624-p 18790-p 12786-p 11898-p 11546-p 10766-p 7654-p 5095
    $ ./pidof -S ' -p ' bash
    ./pidof -S ' -p ' bash
    24624 -p 18790 -p 12786 -p 11898 -p 11546 -p 10766 -p 7654 -p 5095
    $ strace -p $(./pidof -S ' -p ' bash)
    strace -p $(./pidof -S ' -p ' bash)
    strace: Process 24624 attached
    strace: Process 18790 attached
    strace: Process 12786 attached
    ...

Signed-off-by: Masatake YAMATO <yamato@redhat.com>
 parent c9be22a8 master

こんな感じで strace で複数プロセスに一度でアタッチできる! あーべんり〜 わかる〜

[vagrant@localhost procps]$ sudo strace -p $(./pidof nginx -S ' -p ')
strace: Process 9621 attached
strace: Process 9620 attached
strace: Process 9619 attached
[pid  9619] rt_sigsuspend([], 8 <unfinished ...> 👈
[pid  9620] epoll_wait(9,  <unfinished ...> 👈
[pid  9621] epoll_wait(11,  👈

複数のコマンドを組み合わせて同様のことを実現するテクニックはあるのだが、 シンプルな手段があれば越したことはない

procps-ng: sysctl の Segmentation Fault を報告 、の続き

hiboma.hatenadiary.jp

上記のエントリにも書いたのだが、2ヶ月ほど前に procps-ng にバグレポートを投げていたのにようやく反応をもらえて、速攻で fix された

gitlab.com

gitlab.com

なかなかのんびりしているプロジェクトなのだな。また何か見つけたら貢献していこう


(追記)

私が issue を立てる前に、バグを作ってしまった作者自信から修正パッチが ML に投稿されていたとのこと。が、見過ごされていたらしい 😭

running sysctl as non-privileged user causes segmentaion fault (#76) · Issues · procps-ng / procps · GitLab

www.freelists.org

刈場坂峠〜白石峠 🚲

12/30 (金)、2017年 最後の自転車

走行距離 97km、獲得標高 1415m

2017年を平穏にしめくくろう ... という気持ちとは裏腹に、気温0度の峠からダウンヒル中にパンクしたり、昼食が足りなくてハンガーノックになりかけたり、落石で通行止めの峠でルート変更を余儀なくされたり、トラブルだらけだった

続きを読む

procps-ng: sysctl の Segmentation Fault を報告

procps-ng の master の sysctl を使っていたら Segmentation Fault を起こしたので issue をオープンしといた

gitlab.com

問題のあるコミット

以下のような感じ

diff --git a/sysctl.c b/sysctl.c
index 29f31af..be05722 100644
--- a/sysctl.c
+++ b/sysctl.c
@@ -158,6 +158,8 @@ static char *StripLeadingAndTrailingSpaces(char *oneline)
 /*
  * Read a sysctl setting
  */
+#define IOBUFSIZ    (128<<10)
+static char *iobuf;
 static int ReadSetting(const char *restrict const name)
 {
    int rc = 0;
@@ -220,6 +222,9 @@ static int ReadSetting(const char *restrict const name)
 
    fp = fopen(tmpname, "r");
 
+   if (iobuf)
(fp, iobuf, _IOFBF, IOBUFSIZ);
+
    if (!fp) {
        switch (errno) {
        case ENOENT:
@@ -430,6 +435,9 @@ static int WriteSetting(const char *setting)
 
    fp = fopen(tmpname, "w");
 
+   if (iobuf)
+       setvbuf(fp, iobuf, _IOFBF, IOBUFSIZ);
+
    if (!fp) {
        switch (errno) {
        case ENOENT:
@@ -793,6 +801,8 @@ int main(int argc, char *argv[])
    argc -= optind;
    argv += optind;
 
+   iobuf = (char*)malloc(IOBUFSIZ);    /* Allow to fail */
+
    if (DisplayAllOpt)
        return DisplayAll(PROC_PATH);

非特権ユーザで sysctl を実行すると、権限が足りない場合に fopen(3) が EACCESS で失敗して NULL を返すのだが、エラーを確認せずに setvbuf(3) しちゃって ぬるぽ で ガッ SIGSEGV するのだった

$ /usr/local/sbin/sysctl net.ipv4.tcp_fastopen_key
Segmentation fault (core dumped)

$ /usr/local/sbin/sysctl -w vm.overcommit_ratio=0
Segmentation fault (core dumped)

本来は以下のような挙動をとるはず

$ /usr/local/sbin/sysctl net.ipv4.tcp_fastopen_key
sysctl: permission denied on key 'net.ipv4.tcp_fastopen_key'

$ /usr/local/sbin/sysctl -w vm.overcommit_ratio=0
sysctl: permission denied on key 'vm.overcommit_ratio'

感想

  • まだ master ブランチに入ってるだけでリリースされてないので、ささっと直してくれるだろう
  • わりと「うっかり」したバグだよなぁ
  • 何も反応なかったらパッチを送ってみよ