2015年10月アーカイブ

psの使い方

私の場合はこれくらいがいいみたい。
ps -Lwo pid,tid,pgid,ppid,user,%cpu,%mem,rss,wchan:20,command

たいていの人はこれを覚えておくといいんじゃないかと思う。
ps auxwf

場合によってはこんなのとか。
ps auxw --sort rss
ps auxw --sort cpu

ただpsのマニュアルは何度読んでも意味がわからない。みんなpsってどう使ってるんよと・・・

gdb上でattachしてプロセスをデバッグ中にCtrl+Cしてinterruptすることができないという問題を追っていたが、結論はgdbコミュニティ本体側のバグ(gdbserver)のバグだった。

以下のユースケースで問題となる。
・a) remoteシステムのプロセスをgdbserverを使ってデバッグしようとしていて
・b) 動いている途中のプロセスをgdbserver --attachで捕まえて
・c) localシステムのgdbでtarget remoteでリモートでバッグ開始し
・d) 一度 continue して
・e) breakやsignalなどで止まる前にlocalシステムのgdb上でCtrl+Cしてinterruptさせる

このとき、interrupt要求を受けたremoteシステムのgdbserverはattach対象のプロセスにSIGINTを送って止めようとするが、この送るときにkill(-pid, SIGINT)している。結果、プロセスにSIGINTが送られるのではなく、プロセスグループにSIGINTが送られる。すると2つの問題が起こる。

・A) attachしているプロセスがプロセスグループリーダじゃない場合、SIGINTは誰にも送られない。つまりattachしているプロセスにもSIGINTが送られず、attachしているプロセスは止まらない。
・B) attachしているプロセスがプロセスグループリーダの場合、attachしているプロセスを止めてデバッグすることはできるが、同じプロセスグループに属するプロセス(このプロセスの子どもや孫たち)にもSIGINTが送られ、たいていはデフォルトのシグナルハンドラが呼ばれ終了してしまう。

該当バグはこのcommitで入った。78708b7c8ccc2138880217de9bd60eceff683f10 デバッグ対象のプロセスのmainスレッドがすでにexitしていた場合にtpkillではSIGINTを送ることができずinterruptできないという問題を直しているように見える。が、多くの人にとってはここで提唱している問題の方が引っかかる気がするんだが。→ 当時のメールのやりとりのログ

ちなみに、a)でattachではなく最初から動かした場合(gdbserver hostpc:2345 /usr/local/bin/test_program など)、gdbserverがデバッグ対象プロセスをsetpgid()した状態で動かすため、必ずプロセスグループリーダになる。つまり、A)は起こらない、がB)は起こる。

この記事を書くために改めて調べ直してみると、同じことを指摘するBugzilla(#18945)が登録されていた。が、そもそもSIGINTの仕様がはっきりしていない上に、元バグと指摘バグのどっちが大事か(mainスレッドがいない場合に止められないというバグと、gdbserverでattachした場合に止められないというバグ)のどちらを直す方がいいのか、のところで話が止まっている。

でも、ConsoleでCtrl+CしたときにforegroundなプロセスグループにSIGINTが飛ぶ話と、gdbでデバッグ途中にinterruptしようと思ったときにgdbがデバッグ対象プロセスにSIGINTを送るというやり方をしている話とは、仕様の上では全く関係ない話だと思うんだが・・・

というわけで、少なくとも私のところでは非常に困るので、78708b7c8ccc2138880217de9bd60eceff683f10 をrevertさせてもらった。

ちなみに、プロセスグループやConsole上でのCtrl+Cの話を理解してない場合は話についてこれないので、そういう場合はこの辺を読んでください。

pigzで圧縮を並列処理して高速化

- gzip → pigz
- bzip2 → pbzip2
- xz → pxz
マルチスレッド化することで処理が高速化する。Ubuntuあたりだとapt-get install一発で入る。使い方は基本的に置き換え前のものと同じ。コマンド内部的にCPU個数を確認しながら並列化しているようで、並列化数を制限したいとか言う用途でない限りはそのままでよさげ。

tarでも使おうと思ったらこんな感じで。
- tar cvfz filename.tgz path → tar cvf filename.tgz path --use-compress-prog=pigz
- tar cvfj filename.tbz path → tar cvf filename.tbz path --use-compress-prog=pbzip2
- tar cvfJ filename.txz path → tar cvf filename.txz path --use-compress-prog=pxz

いちいち手で打ってらんねーよ ヽ(`Д´)ノ tという場合 ~/bin あたりにSymlink作ってゴニョるといいかもしんない。ただしこの場合、pxzはSymlinkしないように。どうやらpxzは解凍処理以外をするときは内部的にxzへexecして処理をするという方針のようで、ここに対応抜けがあってexecの無限ループから抜けなくなっちゃう。。

似たようなのとしてはGNU Parallelがあるけど、GNU parallel 使用例を見ても個人的にはいまいちピンと来ない。GNU Parallelの場合、CPUマルチコアを使って高速化というよりは、複数サーバにログインして同時並列実行するような用途の方が向いてる気がする。

とまぁ、細かい話は置いといて、tar cvfz や tar xvfz というよくたたくコマンドで十分にうれしいので、~/bin で ln -s /usr/bin/pigz gzip としとくだけで十分に幸せになれそうです。

2016/09/12(Mon)追記、圧縮だけじゃなくて解凍も高速化します。
pxzじゃなくてpixzだと、execの無限ループに入らず、また圧縮も並列化してくれる。ただしUbuntuではまだapt-getモジュール管理されていない模様。

このアーカイブについて

このページには、2015年10月に書かれたブログ記事が新しい順に公開されています。

前のアーカイブは2015年9月です。

次のアーカイブは2015年11月です。

最近のコンテンツはインデックスページで見られます。過去に書かれたものはアーカイブのページで見られます。

月別 アーカイブ

ウェブページ

Powered by Movable Type 7.5.0