ラベル macos の投稿を表示しています。 すべての投稿を表示
ラベル macos の投稿を表示しています。 すべての投稿を表示

2013年9月16日月曜日

Linuxの仮想コンソール切り換え(VMware Fusionにて)

MacBook に VMware Fusion を入れ、ゲストOSに Linux を入れ、コンソールで作業している場合の話。


別のコンソールに切り替えようとすると大抵は間違ったキーを押してしまう。たとえばただ単に B や C の文字がぽつんと表示されておしまいである。これがMacでなければ Alt + F1(F2,...,F6) キーで間違うことはないのだが。。。


この環境で打つべき正しい組み合わせは次のとおり:

optionキー + fnキー + F1(F2,...,F6)


失敗の原因は「option」でなく「command」を押してしまうこと。Macのoptionキーにはよく見ると "alt" という文字も書いてあるので見れば分かるというのに。。。とはいうもののキーボードの表面などは滅多に見ないのだからしかたがない。

2012年7月7日土曜日

Fedora のインストールメディアとUSBメモリ、Mac OS X で作る

今日、Fedora-17 をうちのPCにインストールした。CD-RW, DVD-RWメディアが手元になかったのでUSBメモリを使った。USBメモリへの書き込みには、MacBook(Mac OS X)を使った。ただそれだけの話。しかしながら、いくつかの情報を必要としたのでメモしておく。


Fedoraをインストールするハードウェアは?

まずはハードウェア、なかでもCPUやマザーボードの仕様が分からないといけない。

CPUはAMD Phenom II 64bit で、マザーボードは ASRock の 880GM-LE。このマザーボードは BIOS を使っているモデル(UEFIではない、という点が重要)。

※ASRockのマザーボードAMD8シリーズのリストはこれ:ASRock AMD8


どのファイルをダウンロードすればよいか?

Fedora の場合、「Full Distribution」, 「Live Image」,「Minimal Boot Media」の3つの選択肢がある。今回は、必要なパッケージをあとから追加するスタイルでゆくから Minimal Boot Media がいい。

Minimal Boot Media のISOファイルは「boot.iso」という名前で配布されており、今回はこれで十分。一方、対象のマザーボードがUEFIを使用している場合は注意が必要で、「efiboot.img」を Full Distribution の中から抽出しなければならないらしい。

boot.iso は配布用サーバーの「fedora/linux/releases/17/Fedora/arch/os/images/boot.iso」といったパスに配置されている。


USBメモリにISOイメージを書き込む

MacにUSBメモリを挿して、ISOイメージを書き込む。Fedoraのドキュンメントにddコマンドを使った方法が掲載されているので、これに基づいてやればよい。Linuxを前提として書かれているが、Macにもddコマンドがあるのでそれほど大きな差はない(Mac OS X のコマンドである diskutil を使う点が異なる)。

2012年3月1日木曜日

dd コマンドでファイルを読み書き

ddコマンドはディスクのバックアップやダンプに使われることが多いので、コピー専用のコマンドだと思っていたことがある。

実際はそうではなくて、もっと軽い用途、たとえば標準入力から読み込んだ内容をファイルに書き込んだり、ファイルを読み込んで標準出力に出力したりすることもできる。


入力した内容をファイルに出力
'of'オプションで出力先を指定しつつ ddを実行すると入力待ちになる。そこで任意の文字とEOF(Ctrl-D)を入力すれば、ファイルができる。
$ dd of=hello.txt
hello, world
0+1 records in
0+1 records out
13 bytes transferred in 2.835518 secs (5 bytes/sec)
$ cat hello.txt
hello, world
$
ファイルの内容を表示
'if'でファイルを指定するだけ。
$ dd if=hello.txt 
hello, world
0+1 records in
0+1 records out
13 bytes transferred in 0.000138 secs (94173 bytes/sec)
$
ディスクなどのブロックデバイスファイルの場合も同様に表示できる。ただしサイズが大きいので 'bs' や 'count' オプションで調節する。
$ sudo dd if=/dev/disk0 bs=5 count=1  # MacOS requires root privilege to read /dev/disk0
?1???1+0 records in
1+0 records out
5 bytes transferred in 0.000334 secs (14969 bytes/sec)
$

2012年1月15日日曜日

Mac OS X: fsck reports benign errors when journaling is turned on

support.apple.com に、MacOS X で fsck のエラーが出ても気にしなくてよいよ、と書いてあった(JHFS+などのジャーナリングファイルシステムを使っている場合の話)。


Mac OS X: diskutil -- Modify, verify and repair local disks.

Mac OS にインストールされている、ディスクユーティリティコマンド。ディスク状態の確認、パーティションの作成、マージなどに使える。

diskutil によると、このコマンドはAppleが用意したもので、普通のBSDには入っていないらしい。


自分が使ったものだけメモしておく。

diskutil list
ディスクと、ディスク内のパーティションを一覧表示。
$ diskutil list
/dev/disk0
   #:                       TYPE NAME                    SIZE       IDENTIFIER
   0:      GUID_partition_scheme                        *250.1 GB   disk0
   1:                        EFI                         209.7 MB   disk0s1
   2:                  Apple_HFS Macintosh HD            249.7 GB   disk0s2
/dev/disk1
   #:                       TYPE NAME                    SIZE       IDENTIFIER
   0:        CD_partition_scheme Gateway                *442.3 MB   disk1
   1:                      CD_DA                         75.3 KB    disk1s0
   2:                      CD_DA                         83.6 MB    disk1s1
   3:                      CD_DA                         23.5 MB    disk1s2
   4:                      CD_DA                         117.1 MB   disk1s3
   5:                      CD_DA                         51.5 MB    disk1s4
   6:                      CD_DA                         50.7 MB    disk1s5
   7:                      CD_DA                         115.8 MB   disk1s6
SATAのHDD(disk0)と、CD-ROM(disk1)を認識しているのが分かる。
disk0 は"GUID_partition_scheme"というTYPEになっているので、MBRではなくGPTが書かれているのが分かる。
disk1 のほうは"Gateway"という名前になっているが、これは "Amazon.com: Gateway: John Abercrombie, Dave Holland, Jack Dejohnette: Music" という音楽作品である。
diskutil info
ディスクまたはパーティションの詳細情報を表示。次の実行例は、"SMART"情報だけを grep したもの。
$ diskutil info disk0|grep SMART
   SMART Status:             Verified
diskutil mergePartitions
パーティションをマージする。ファイルシステムと名前、マージするパーティション(複数)を引数で与える。最初に指定したパーティション以外のパーティションは消える。"JHFS+" は Journaled HFS+ のこと。
# diskutil mergePartitions JHFS+ new disk0s2 disk0s3


2011年12月26日月曜日

OpenSSHのStrictHostKeyChecking=xxx

OpenSSH の'StrictHostKeyChecking'オプションの振る舞いを確認してみた。

環境

ローカルホスト(SSHクライアント)
MacOS 10.6.8, OpenSSH_5.2p1, OpenSSL 0.9.8r 8 Feb 2011
リモートホスト(SSHサーバ)
CentOS-6.0 OpenSSH_5.3p1, OpenSSL 1.0.0-fips 29 Mar 2010

ちなみに OpenSSH のバージョンを調べるオプションは '-V' だった。

やったこと

OpenSSHの'StrictHostKeyChecking'オプションの値を yes, ask, no と変えながら、リモートホスト(ここでは 192.168.111.103)にユーザー user01 でログインを試みる。ただし、毎回以下のコマンドを実行してローカルホストのknown_hostsファイルがリモートホストの情報を含まない状態にしておく。

$ ssh-keygen -R 192.168.111.103

結果

yes の場合
$ ssh -o StrictHostKeyChecking=yes -l user01 192.168.111.103
No RSA host key is known for 192.168.111.103 and you have requested strict checking.
Host key verification failed.
$
認証まで進まずに、sshコマンドが終了してしまう。
ask の場合
ssh -o StrictHostKeyChecking=ask -l user01 192.168.111.103
The authenticity of host '192.168.111.103 (192.168.111.103)' can't be established.
RSA key fingerprint is 26:f9:16:77:cf:92:95:58:95:d1:55:ce:d2:9e:34:84.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '192.168.111.103' (RSA) to the list of known hosts.
user01@192.168.111.103's password:
手続きを進めるかどうか確認待ちになる。そこで yes を入力すると、パスワード入力待ちになる。
no の場合
$ ssh -o StrictHostKeyChecking=no -l user01 192.168.111.103
Warning: Permanently added '192.168.111.103' (RSA) to the list of known hosts.
user01@192.168.111.103's password:
確認無しに、パスワード入力待ちになる。

2011年8月20日土曜日

Tunnelblick の WARNING

Tunnelblick というのは、Mac用のOpenVPNクライアント。

今日まで気がつかなかったが、ログを見ると次のようなWARNINGが出ていた。

2011-08-20 00:13:31 WARNING: No server certificate verification method has been enabled.  See http://openvpn.net/howto.html#mitm for more info.

バージョンは *Tunnelblick: OS X 10.6.8; Tunnelblick 3.1.7 (build 2190.2413); OpenVPN 2.1.4

よくあること?

ほかの人のブログにも同じWARNINGが出てるケースが散見されるし、OpenVPNを使ううえで問題はないので、無視してよいのかもしれない。

…が、やはり気になったので調べた。

原因と解決策

実は Tunnelblick の設定ファイル( config.ovpn )が微妙に間違っていて、証明書や秘密鍵を参照できてなかった様子。念のため絶対パスで記述したらWARNINGが出なくなった。

修正前
ca ca.crt
cert client01.crt
key client01.key
修正後
ca /Users/foo/Library/openvpn/TunnelblickVPNConfigurationClient01.tblk/Contents/Resources/ca.crt
cert /Users/foo/Library/openvpn/TunnelblickVPNConfigurationClient01.tblk/Contents/Resources/client01.crt
key /Users/foo/Library/openvpn/TunnelblickVPNConfigurationClient01.tblk/Contents/Resources/client01.key

ここで、fooTunnelblickVPNConfigurationClient01 はそれぞれ Macユーザ名と Tunnelblickの設定名称なので環境に依存する。

2011年8月4日木曜日

オイラー・丸山法とPythonのMatplotlib

MatplotlibはPython向けの2次元プロットライブラリ。Wikipediaの記事「Euler-Maruyama method - Wikipedia, the free encyclopedia」(確率微分方程式の数値解法「オイラー・丸山法」)の、サンプルプログラムの中で使われていたので、インストールすることになった。

以下、Mac OS 10.6.8にMatplotlibをインストールして、Wikipediaのサンプルプログラムを実行したという話。

Matplotlibのインストール

Mac OSの場合、特にMacPortsやHomebrewなどのパッケージ管理ソフトを使っているとインストールがうまくいかないことが多いらしい。というのは、Matplotlibが最新の共有ライブラリにリンクされずに、パッケージ管理ソフトであらかじめ導入されていた別の共有ライブラリにリンクされる、といった現象が起こりやすいから。開発者の人も認識しているようで、README.osxというファイルに"Building mpl on OSX has proven to be a nightmare because of all the different types of zlib, png and freetype that may be on your system."と書いてあった(まるでナイトメアらしい)。

Mac OS X 10.6.8 (Darwin 10.8.0 x86_64) では、次の手順でインストールができた。

1. PythonとNumPyを確認

前提条件として、Python 2.5以上と、NumPyモジュール(version 1.1以上)が必要とのこと。これは以下のコマンドで確認できる。

$ python --version
Python 2.6.1
$ python -c "import numpy;print numpy.__version__"
1.2.1

自分で入れたのか最初から入っていたのか記憶が無いが、とりあえず自分の場合はすでに必要なものがインストールされていた。

2. githubからMatplotlibを取得
$ git clone https://github.com/matplotlib/matplotlib.git
3. make.osxの一部を書きかえる
$ cd matplotlib
$ vi make.osx
$ git diff make.osx
diff --git a/make.osx b/make.osx
index 4639eac..8dc60c7 100644
--- a/make.osx
+++ b/make.osx
@@ -3,6 +3,7 @@
 # make -f make.osx PREFIX=/Users/jdhunter/dev PYVERSION=2.6 fetch deps mpl_install
 # (see README.osx for more details)
 
+PREFIX=/usr/local
 MPLVERSION=1.1.0
 PYVERSION=2.6
 PYTHON=python${PYVERSION}
@@ -16,8 +17,8 @@ ARCH_FLAGS=-arch i386 -arch x86_64
 # but the download URLs are subject to change.
 
 ZLIBVERSION=1.2.5
-PNGVERSION=1.5.1
-FREETYPEVERSION=2.4.4
+PNGVERSION=1.5.4
+FREETYPEVERSION=2.4.6

変更点は3つ。第一に、共有ライブラリのインストールパスを"/usr/local/lib"にしたいので、PREFIX=/usr/local を追加。それから、libpng と freetype のバージョンを現時点で最新の番号にした。

4. makeする
$ make -f make.osx fetch deps mpl_install_std

これを実行すると、fetch, deps, mpl_install_stdという3つのターゲットが処理される。fetchがzlib等のライブラリのソースをダウンロードしてきて、depsがライブラリのコンパイルとインストールをして、最後にmpl_install_stdがMatplotlib自身のコンパイルとインストールを行う流れ。

完了したら、/usr/local/lib/Library/Python/2.6/site-packages/matplotlib を確認してみる。

$ ls -t1 /usr/local/lib/
libz.1.2.5.dylib
libz.1.dylib
(略)

$ ls -t1 /Library/Python/2.6/site-packages/matplotlib
mlab.pyc
mpl.pycf
offsetbox.pyc
(略)

$ otool -L /Library/Python/2.6/site-packages/matplotlib/_png.so
/Library/Python/2.6/site-packages/matplotlib/_png.so:
 /usr/local/lib/libpng15.15.dylib (compatibility version 20.0.0, current version 20.0.0)
 /usr/local/lib/libz.1.dylib (compatibility version 1.0.0, current version 1.2.5)
 /usr/lib/libstdc++.6.dylib (compatibility version 7.0.0, current version 7.9.0)
 /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 125.2.0)

ポイントは(1)共有ライブラリができていて、(2)matplotlibのモジュールができていて、(3)モジュール内の共有ライブラリが(1)の共有ライブラリに依存していることの3つ。

オイラー・丸山法

常微分方程式の世界における「オイラー法」に対応するのが「オイラー・丸山法」らしい。「丸山」のフルネームは丸山儀四郎。

Euler-Maruyama method - Wikipedia, the free encyclopedia のExample code(Python)をそのままコピー&実行するとグラフができる。

コードでrandomとか使ってるからあたり前だけど、「実行する度に結果が変わってOK」という考えが新鮮。これまで確定的な微分方程式の数値計算しか扱ったことが無かったので変な感じがする。

ざっと検索したところ、普通のプログラミング環境ではなくエクセルを使って計算する人もいる(そういう方向性の本が出版されている)。

Mac OS で XZ形式アーカイブを使う

今日まで知らなかったが、Mac OS標準のコマンドでは "tar xJf *.tar.xz" ができない。

大抵は gzip か bzip2 を使えば済む話だが、どうしても xz しか選択肢が無い状況なら XZ utils と GNUのtarをインストールするとよい(詳しいことは「Mac で XZ 形式を圧縮・解凍したいときの備忘録 - takkan_mのNo planな日常」に書いてあった)。

あとどうでもいいが tar のオプションは人によって揺らぐ。Jxf だったり xJf だったり -Jxf だったり… 自分の場合は xc が必ず最初に来る。コマンドを打つとき、開く(x)か閉じる(c)かが最初に頭の中で決まるから。

2011年8月2日火曜日

コマンドを手軽にマルチプロセス実行 GNU Parallel

GNU Parallelというプログラムを今さら知ったのでメモしておく。これは、複数のプログラムを並行して実行したいときに便利。

インストール

GNU Parallelのダウンロードページから最新版の parallel-20110722.tar.bz2 をダウンロードし、configure, make, make install する。

$ wget ftp://ftp.gnu.org/gnu/parallel/parallel-20110722.tar.bz2
$ tar xvjf parallel-20110722.tar.bz2
$ cd parallel-20110722
$ ./configure
$ make
$ sudo make install

ちなみに環境は Darwin 10.8.0 x86_64。

試してみる

とりあえずPerlで簡単なプログラムを作って試す。

print_argv0.pl
#!/usr/bin/perl
sleep(1);
print "$ARGV[0]\n";
exit;
1秒間スリープして引数を表示するだけのもの。これにlsの結果を入力する処理を、prallelコマンド経由で実行してみる。
同時に実行するジョブ数 = 20 で実行した場合(-jオプション)
$ time ls|parallel -j 20 ./print_argv0.pl {}
COPYING
Makefile
Makefile.am
Makefile.in
NEWS
README
aclocal.m4
config.h
config.h.in
config.log
config.status
configure
configure.ac
install-sh
missing
print_argv0.pl
src
stamp-h1

real 0m1.396s
user 0m0.229s
sys 0m0.259s
1.396s で終了したので、確かに同時に実行されている様子。lsの結果が18行なので順番に実行すれば18秒はかかってしまうはず。
ジョブ数 = 1 で実行した場合
$ time ls|parallel -j 1 ./print_argv0.pl {}
COPYING
Makefile
Makefile.am
Makefile.in
NEWS
README
aclocal.m4
config.h
config.h.in
config.log
config.status
configure
configure.ac
install-sh
missing
print_argv0.pl
src
stamp-h1

real 0m18.517s
user 0m0.231s
sys 0m0.243s
19.517s かかった。

プロセス

ついでにプロセスの状態を調べるため、ジョブの数を3にして parallel をバックグラウンド実行した後、psコマンドを打ってみた。

$ time ls|parallel -j 3 ./print_argv0.pl {} &
[1] 5140
$ ps axl
  UID   PID  PPID CPU PRI NI      VSZ    RSS WCHAN  STAT   TT       TIME COMMAND
(略)
  501  5142  5140   0  29  0  2443672   8584 -      S      p0    0:00.18 /usr/bin/perl -w /usr/local/bin/parallel -j 3 ./print_argv0.pl {}
  501  5172  5142   0  30  0  2437344   1048 -      S      p0    0:00.01 /usr/bin/perl ./print_argv0.pl Makefile.in
  501  5173  5142   0  30  0  2437344   1048 -      S      p0    0:00.01 /usr/bin/perl ./print_argv0.pl NEWS
  501  5174  5142   0  31  0  2437344   1048 -      S      p0    0:00.01 /usr/bin/perl ./print_argv0.pl README
(略)

parallel自体もperlで書かれており、/usr/bin/perl -w により実行されている(プロセスID 5142)。中ではforkしているらしく、子プロセスが3つ生成されている(5172, 5173, 5174)。

2011年7月29日金曜日

ネットワークのベンチマークソフト Netperf

netperf は TCP/UDP, Unix Domain Sockets などのスループットを計測できるソフトの一つ。ここで言う「スループット」は単位時間あたりのデータ転送量のこと。

これを使うためには、ネットワーク内で通信を行う両ホストにインストールしておく必要がある。インストール後は、まず一方のホストでサーバープログラム(netserver)を起動して、もう一方のホストでクライアントプログラム(netperf)を実行するという手順。デフォルト動作では、サーバーは12865番ポートをListenする模様(場合によっては通信できるよう開けておく必要がある)。

CentOS 6へのインストール

rpmforgeのレポジトリを使えば yum でインストールできる。

rpmforgeを参照するための設定は、「CentOS 6 - 初期設定 - yum用リポジトリ追加 : Server World」に詳しく書いてある。

# yum --enablerepo=rpmforge install netperf

Mac OS X へのインストール(Mac OS 10.6.8)

MacPortsでインストールできるらしいが、MacPortsをあまり使っていないので、ソースをコンパイルして入れた。

$ wget ftp://ftp.netperf.org/netperf/netperf-2.5.0.tar.bz2
$ tar xvjf netperf-2.5.0.tar.bz2
$ cd netperf-2.5.0
$ ./configure
$ make
$ make check
$ sudo make install

実行例

こんな感じで結果が出力される。

$ netperf -H 192.168.1.20
MIGRATED TCP STREAM TEST from (null) (0.0.0.0) port 0 AF_INET to (null) (192.168.1.20) port 0 AF_INET
Recv   Send    Send                          
Socket Socket  Message  Elapsed              
Size   Size    Size     Time     Throughput  
bytes  bytes   bytes    secs.    10^6bits/sec  

262140 131070 131070    10.00    14149.31

2011年7月19日火曜日

Mach-Oファイル形式と、それにまつわるツール

「Mach-O」とは Mac OS X におけるオブジェクトファイルのフォーマットのこと(LinuxにおけるELFみたいなもの)。詳しいことは apple.com のドキュメント「Mac OS X ABI Mach-O File Format Reference」にとても分かりやすく書いてある。

LinuxのELFなら readelfldd などでオブジェクトファイルを解析できる。一方、Mach-O の場合はどうすればいいのだろうか。このあたり、実際に手を動かして調べたことを記録しておく。

Mach-Oフォーマットに関する雑感

  • ELFより分かりやすい気がする(とりあえず「プログラムヘッダ」「セクションヘッダ」のような二面性がない)
  • Mach header, load commands, segments, segments の中の sections で構成されている
  • segmentは6種類だけ(__PAGEZERO, __TEXT, __DATA, __OBJC, __IMPORT, __LINKEDIT)
  • segment と sections の名前は、それぞれ大文字、小文字で表す(命名規約)

otoolコマンド

Linuxの"readelf"みたいなコマンドで、Mach-Oの情報をフォーマットして出力してくれる。オプション-vで人間向けのシンボリックな表示になる。

Machヘッダ
$ otool -hv /bin/ls
/bin/ls:
Mach header
      magic cputype cpusubtype  caps    filetype ncmds sizeofcmds      flags
MH_MAGIC_64  X86_64        ALL LIB64     EXECUTE    13       1928   NOUNDEFS DYLDLINK TWOLEVEL
__TEXTセグメントの中の __textセクション
$ otool -tv /bin/ls
/bin/ls:
(__TEXT,__text) section
0000000100001478 pushq $0x00
000000010000147a movq %rsp,%rbp
000000010000147d andq $0xf0,%rsp
(略)
__DATAセグメントの中の __dataセクション
$ otool -dv /bin/ls|head
/bin/ls:
(__DATA,__data) section
0000000100006540 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
0000000100006550 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
0000000100006560 50 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
(略)
共有ライブラリの依存関係。Linuxでの lddコマンドに相当
$ otool -Lv /bin/ls
/bin/ls:
 /usr/lib/libncurses.5.4.dylib (compatibility version 5.4.0, current version 5.4.0)
 time stamp 2 Thu Jan  1 09:00:02 1970
 /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 123.0.0)
 time stamp 2 Thu Jan  1 09:00:02 1970

sizeコマンド

セグメントのサイズを表示してくれるコマンド。オプション無しなら __TEXT, __DATA, __OBJC, その他, 全体 を表示。オプション有り(-mなど)だと、すべてのセグメントについて表示。

オプションなし
$ size /bin/ls
__TEXT __DATA __OBJC others dec hex
24576 4096 0 4294979584 4295008256 10000a000
-m オプション
$ size -m /bin/ls
Segment __PAGEZERO: 4294967296
Segment __TEXT: 24576
 Section __text: 14575
 Section __symbol_stub1: 456
 Section __stub_helper: 776
 Section __cstring: 1199
 Section __const: 56
 Section __unwind_info: 188
 Section __eh_frame: 2072
 total 19322
Segment __DATA: 4096
 Section __nl_symbol_ptr: 56
 Section __la_symbol_ptr: 608
 Section __program_vars: 40
 Section __const: 600
 Section __data: 76
 Section __bss: 228
 Section __common: 140
 total 1748
Segment __LINKEDIT: 12288
total 4295008256

nmコマンド

Linuxでおなじみのコマンドだが(GNU の binutils に入ってる)、Macにも同じ名前のコマンドがあった。U, sなどのシンボルの意味はLinuxとだいたい一緒かな。

実行ファイルの場合
$ nm /bin/ls
                 U __DefaultRuneLocale
                 U ___assert_rtn
                 U ___error
(略)
共有ライブラリの場合
$ nm /usr/lib/libSystem.B.dylib
000000000014331a s  stub helpers
000000000017a1e6 S $ld$hide$os10.4$__Unwind_Backtrace
000000000017a1d0 S $ld$hide$os10.4$__Unwind_DeleteException
(略)

2011年7月17日日曜日

Mac OS XのプロファイラSharkをコマンドラインで

MacでCプログラムを書いていて、プロファイルを調べたくなった。Linuxであればgprofを使うので、とりあえず"which gprof"してみたらMac OSにも入っていた。

しかし、実際に使ってみると期待どおりに動かない。呼出回数は計測されるが時間が計測されないらしく、次の例のように 0.0 が並んでしまった。

$ gprof foo gmon.out
(中略)
  %   cumulative   self              self     total           
 time   seconds   seconds    calls  ms/call  ms/call  name    
  0.0       0.00     0.00   200001     0.00     0.00  _main [79]
  0.0       0.00     0.00   200000     0.00     0.00  _f1 [80]
  0.0       0.00     0.00   200000     0.00     0.00  _f2 [81]
  0.0       0.00     0.00   100000     0.00     0.00  _f3 [82]
  0.0       0.00     0.00        1     0.00     0.00  __start [83]

環境は以下のとおり。

$ uname -mrs
Darwin 10.8.0 x86_64

Shark

調べたところ Mac OS で gprof の動作が不完全なのはFAQというか一般常識。代わりに"Shark"を使うのが定石らしい。

そのShark、「MacOSXではgprofが使えない→Sharkを使う - 西尾泰和のはてなダイアリー」で紹介されているように、確かにこれで間に合うのだが、GUIなのが面倒でツラい。1つのプロセスのプロファイルが欲しいのに、たくさんのプロセスを一度にプロファイリングしてその中から選ぶのも冗長な気がしてしまう。

Sharkをコマンドラインで

man shark してみたら実はコマンドラインからも使えて、テキスト形式のレポートも簡単に生成できることがわかった。

以下はfooというプログラムのプロファイルをとってレポートする例。

$ shark -1 -G -i ./foo
shark 4.7.3 (383)
* Option+Esc to start/stop a trace session
* Ctrl+c to stop sampling and quit (any pending samples are processed and saved)

* Batch mode
* Watching task exits
* Profiling limited to foo (PID #33472)

Sampling Config: Time Profile
Timed Samples & Counters
-Sampling begins immediately.
-A sample is taken every 1ms.
-Sampling ends automatically after 30s.



Ready. 

Sampling...
0    #これはプログラムfooが出力した数字

Processing samples...( Ctrl-c will cancel processing; No session will be created. )


CHUDData - Analyzing samples...

(略。WARNINGが出力される…)

sharkコマンドが終わると、カレントディレクトリにファイルが2個生成される。

一つは "session_001.mshark" で、shark的には session file と呼ばれるバイナリ。プロファイルの1セッション分の情報が記録されていると思われる。

もう一つは"session_001-report.txt" で、これがテキストのレポート。次のような内容になっている。長い。

$ cat session_001-report.txt 

================================================================================
Session
================================================================================
Authored by: dminor11th on 2011-07-17 19:13:45 +0900 (started 2011-07-17 19:13:32 +0900)
Version: Shark 4.7.3-383 (Session v0.3.0)
Host: dminor11th-MacBookPro.local
Operating System: Mac OS X 10.6.8 (10K540)
Machine Class: MacBookPro5,5
Memory: 4096 MB
Processor: 2 x 2530/1064 MHz Intel Core 2 (Penryn) v7.0
Memory Controller: Unknown
IO Controller: UnknownCHUD.framework: v4.7.3
CHUDProf.kext: v366
CHUDUtils.kext: Unknown

================================================================================
Sampling Configuration
================================================================================
Timed Samples & Counters
-Sampling begins immediately.
-A sample is taken every 1ms.
-Sampling ends automatically after 30s.


================================================================================
Module: SharkProfileAnalysis
================================================================================
REPORT:


================================================================================
Active Process Summary
================================================================================
Process [PID]                     % Total
-----------------------------------------
foo [33472]                  100.0%
-----------------------------------------
Total                              100.0%

Process [PID]                     # Total
-----------------------------------------
foo [33472]                   12107
-----------------------------------------
Total                               12107

===============================================================================================
  foo [33472]
    % Total                               Symbol                  Library      Address   Length
-----------------------------------------------------------------------------------------------
      58.4%                              strncmp /usr/lib/libSystem.B.dylib 0x7fff8833c280     0xe5
      20.0%                                  f2 /Users/dminor11th/temp/foo  0x100000863    0x14c
      18.1%                                  f3 /Users/dminor11th/temp/foo  0x100000a8d     0x81
       2.4%                    dyld_stub_strncmp /Users/dminor11th/temp/foo  0x100000dae      0x6
       0.1%                           __vfprintf /usr/lib/libSystem.B.dylib 0x7fff8834662c   0x5304
       0.1%                              __bzero /usr/lib/libSystem.B.dylib 0x7fffffe00600    0x180
       0.1%                            vsnprintf /usr/lib/libSystem.B.dylib 0x7fff8837b454    0x194
(略)

「あーあ、strncmpが58.4%か…」みたいな感じ。

以上、sharkについて。これでとりあえずは Mac OS でのプロファイラには困らないかなと。