Just another Ruby porter,


1月下旬の日記 | RDF

2015-01-29 (Thu)

libcを検索してどうする

GHOSTが話題だが このページにあるglibcを使ってるプロセスを探す方法はつっこまずにはいられない。

$ lsof | grep libc | awk '{print $1}' | sort | uniq

コメントでawkだのsort -uを使えば短くなるとかあるのはまあお約束として、問題はlibcで検索してるところ。

% lsof |grep -o 'libc.*' | sort -u
libc-2.19.so
libc.mo
libcairo-gobject.so.2.11301.0
libcairo.so.2.11301.0
libcanberra-0.30/libcanberra-pulse.so
libcanberra-gtk-module.so
libcanberra-gtk.so.0.1.9
libcanberra-gtk3-module.so
libcanberra-gtk3.so.0.1.9
libcanberra.so.0.2.5
libcap-ng.so.0.0.0
libcap.so.2.24
libcgmanager.so.0.0.0
libcom_err.so.2.1
libcpufreq.so.0.0.0
libcpugraph.so
libcroco-0.6.so.3.0.1
libcrypt-2.19.so
libcrypto.so.1.0.0
libcups.so.2
libcurl.so.4.3.0

libcで始まるライブラリはいっぱいあるわけで。

というよりもすべてのプロセスはlibcに依存していると言っていいわけで、
libcで検索すること自体ナンセンス。

lsofは引数で指定したファイルをopenしているプロセスを表示してくれるので、
たとえばlibcrypto.soを使ってるのを探したければ、こんな感じでok。

% lsof /lib/x86_64-linux-gnu/libcrypto.so.1.0.0
COMMAND     PID USER  FD   TYPE DEVICE SIZE/OFF     NODE NAME
python     2958 eban mem    REG    8,2  1961344 43253810 /lib/x86_64-linux-gnu/libcrypto.so.1.0.0
python     2967 eban mem    REG    8,2  1961344 43253810 /lib/x86_64-linux-gnu/libcrypto.so.1.0.0
python     2979 eban mem    REG    8,2  1961344 43253810 /lib/x86_64-linux-gnu/libcrypto.so.1.0.0
indicator  2990 eban mem    REG    8,2  1961344 43253810 /lib/x86_64-linux-gnu/libcrypto.so.1.0.0
ssh        3435 eban mem    REG    8,2  1961344 43253810 /lib/x86_64-linux-gnu/libcrypto.so.1.0.0
ssh        3438 eban mem    REG    8,2  1961344 43253810 /lib/x86_64-linux-gnu/libcrypto.so.1.0.0
ssh        3611 eban mem    REG    8,2  1961344 43253810 /lib/x86_64-linux-gnu/libcrypto.so.1.0.0
ssh        3622 eban mem    REG    8,2  1961344 43253810 /lib/x86_64-linux-gnu/libcrypto.so.1.0.0
ssh        3636 eban mem    REG    8,2  1961344 43253810 /lib/x86_64-linux-gnu/libcrypto.so.1.0.0
ruby       3748 eban mem    REG    8,2  1961344 43253810 /lib/x86_64-linux-gnu/libcrypto.so.1.0.0
x11vnc    22351 eban mem    REG    8,2  1961344 43253810 /lib/x86_64-linux-gnu/libcrypto.so.1.0.0
w3m       25870 eban mem    REG    8,2  1961344 43253810 /lib/x86_64-linux-gnu/libcrypto.so.1.0.0

2015-01-28 (Wed)

convertの引数の順番はやはり大事

PDFを画像にするときの定番にconvertがある。
-densityで指定しても低いままだなあとずっと思っていたが、
これも順番がものすごく大事だとわかった。
たとえば

% convert foo.pdf -density 300 foo.jpg

とかやりがちだが、これだと全然意味がない。

% convert -density 300 foo.pdf foo.jpg

のようにfoo.pdfの前に-densityを置く。-verboseをつけるとよくわかる。

% convert -verbose '残照.pdf[1]' -density 300 /tmp/foo.jpg
"gs" -q -dQUIET -dSAFER -dBATCH -dNOPAUSE -dNOPROMPT -dMaxBitmap=500000000 -dAlignToPixels=0 -dGridFitTT=2 "-sDEVICE=pngalpha" -dTextAlphaBits=4 -dGraphicsAlphaBits=4 "-r72x72" -dFirstPage=2 -dLastPage=2 "-sOutputFile=/tmp/magick-_Uc3SdUw-%08d" "-f/tmp/magick-qPsh2kGe" "-f/tmp/magick-fujmhwsW"
/tmp/magick-_Uc3SdUw-00000001 PNG 298x496 298x496+0+0 8-bit DirectClass 4.22KB 0.010u 0:00.000
残照.pdf[1]=>残照.pdf[1] PDF 298x496 298x496+0+0 16-bit DirectClass 0.000u 0:00.000
残照.pdf[1]=>/tmp/foo.jpg[1] PDF 298x496 298x496+0+0 16-bit DirectClass 0.000u 0:00.000

内部的にはgsが変換してるが、-r72x72となってる。つまり-density 72ということだ。
これはconvertのデフォルトの値と思われる。
ファイル名の後に-density 300を指定しても後の祭りということになる。

% convert -verbose -density 300 '残照.pdf[1]' /tmp/foo.jpg
"gs" -q -dQUIET -dSAFER -dBATCH -dNOPAUSE -dNOPROMPT -dMaxBitmap=500000000 -dAlignToPixels=0 -dGridFitTT=2 "-sDEVICE=pngalpha" -dTextAlphaBits=4 -dGraphicsAlphaBits=4 "-r300x300" -dFirstPage=2 -dLastPage=2 "-sOutputFile=/tmp/magick-YslpFx3t-%08d" "-f/tmp/magick-XPhLyekZ" "-f/tmp/magick-mVgnGZAu"
/tmp/magick-YslpFx3t-00000001 PNG 1240x2066 1240x2066+0+0 8-bit DirectClass 17.3KB 0.060u 0:00.060
残照.pdf[1]=>残照.pdf[1] PDF 1240x2066 1240x2066+0+0 16-bit DirectClass 0.000u 0:00.000
残照.pdf[1]=>/tmp/foo.jpg[1] PDF 1240x2066 1240x2066+0+0 16-bit DirectClass 16.4KB 0.040u 0:00.039

これで-r300x300になった。


2015-01-27 (Tue)

commとjoinの速度

5000万ぐらいになるとfgrepでも結構苦しくなる。

% seq 50000000 | sed 5000d > nums50M
% time seq 50000000 | fgrep -xv -f nums50M 
5000
seq 50000000  0.99s user 0.25s system 1% cpu 1:55.80 total
fgrep -xv -f nums50M  113.18s user 2.62s system 99% cpu 1:56.03 total

2分近くかかっている。少しでも速く実行したいならjoinやcommを使う。

% time seq 50000000 | sort | join -v1 - <(sort nums50M)
5000
seq 50000000  0.77s user 0.13s system 7% cpu 12.189 total
sort  15.41s user 1.81s system 35% cpu 48.196 total
join -v1 - <(sort nums50M)  8.13s user 0.28s system 17% cpu 48.195 total
% time seq 50000000 | sort | comm -23 - <(sort nums50M)
5000
seq 50000000  0.81s user 0.14s system 9% cpu 9.953 total
sort  15.62s user 1.96s system 41% cpu 42.238 total
comm -23 - <(sort nums50M)  4.22s user 0.28s system 10% cpu 42.237 total

2倍以上速い。実はほとんどソートしてる時間だったりする。
あらかじめソートしといていいなら10秒かからない。

% seq 50000000 | sort > seq50Ms
% seq 50000000 | sed 5000d | sort > nums50Ms
% time join -v1 seq50Ms nums50Ms                  
5000
join -v1 seq50Ms nums50Ms  6.95s user 0.10s system 99% cpu 7.060 total
% time comm -23 seq50Ms nums50Ms
5000
comm -23 seq50Ms nums50Ms  3.52s user 0.11s system 99% cpu 3.633 total

grepの代わりになって実はうれしいのである。


2015-01-26 (Mon)

250じゃなくて10万だとOOM Killer

例の問題はgrepで250ぐらいならなんともないが、
10万ぐらいになると8GBあってもメモリが足りなくなる。

% seq 100000 | sed 5000d > nums100K     
% time seq 100000 | grep -xv -f nums100K
zsh: broken pipe  seq 100000 | 
zsh: killed       grep -xv -f nums100K
seq 100000  0.00s user 0.00s system 0% cpu 19:12.16 total

/var/log/syslogを見るとOOM Killerに殺されていた。

Jan 26 23:07:41 m kernel: [ 1572.506071] Out of memory: Kill process 7702 (grep) score 922 or sacrifice child
Jan 26 23:07:41 m kernel: [ 1572.506073] Killed process 7702 (grep) total-vm:15207580kB, anon-rss:7427400kB, file-rss:0kB

こういうときはどうするかというとfgrepを使う。

% time seq 100000 | fgrep -xv -f nums100K 
5000
seq 100000  0.00s user 0.00s system 1% cpu 0.191 total
fgrep -xv -f nums100K  0.06s user 0.00s system 33% cpu 0.194 total

まじかっていうほどあっさり通る。正規表現がいかにメモリを食うかがわかる例。


2015-01-25 (Sun)

例の250の問題をgrepで #シェル芸

よく考えてみたらcommを使わなくてもgrepでいけるのであった。

% seq 250 | sed 128d > nums      
% seq 250 | grep -xv -f nums
128
% seq 250 | sed '50d;128d;200d' > nums       
% seq 250 | grep -xv -f nums
50
128
200

-xは強制的に行全体でPATTERNの一致処理を行うという意味。^と$がつく感じ。
この場合は-wでもいいが、空白とか含まれる場合は-xが必須となる。
sortする必要もないし、こっちのほうがいいかも。


1月下旬の日記 | RDF


WWW を検索 jarp.does.notwork.org を検索

わたなべひろふみ
Key fingerprint = C456 1350 085F A320 C6C8 8A36 0F15 9B2E EB12 3885
Valid HTML 4.01!