X

Oracle Solaris, Oarcle ハードウェア製品に関する情報

  • Sun
    March 27, 2008

動作しているプロセスが、32 bit または 64 bit バイナリのどちらか?

Guest Author
「いま動作しているプロセスが、32 bit か 64 bit か確認する方法はあるか?」と聞かれたのですが、コマンド一発で確認する方法を考えてみました。
例えば、ある実行可能なコマンドが、32 bit バイナリか 64 bit バイナリかは、file コマンドにて確認することが可能ですね。
SPARC の場合

32 bit バイナリ
$ file /usr/bin/truss
/usr/bin/truss: ELF 32-bit MSB executable SPARC Version 1, dynamically linked, stripped
sunfish(SUNW,Ultra-60):/usr/bin/sparcv9

64 bit バイナリ
$ file /usr/bin/sparcv9/truss
/usr/bin/sparcv9/truss: ELF 64-bit MSB executable SPARCV9 Version 1, dynamically linked, stripped

x86 の場合

32 bit バイナリ
$ file /usr/bin/truss
/usr/bin/truss: ELF 32-bit LSB executable 80386 Version 1, dynamically linked, stripped

64 bit バイナリ
$ file /usr/bin/amd64/truss
/usr/bin/amd64/truss: ELF 64-bit LSB executable AMD64 Version 1, dynamically linked, stripped

では、動作しているプロセスが 32 bit か 64 bit か判別するにはどのようにすればよいでしょうか?

Solaris は、64 bit OS であるため、いくつかのコマンドやライブラリは、64 bit バイナリとして提供されてはいますが、いまだ、32 bit バイナリも多く含まれています。
また、アプリケーションによっては、32/64 bit バイナリを同梱している場合もあります。
64 bit 環境を生かすべく、64 bit バイナリが動作しているかと思っていたら、実は 32 bit バイナリがサービスを提供していた・・・なんてことになっているかも・・・
そのような環境の中で、目的のバイナリが適切に動作しているかを確認する必要がでてくる場合があるかもしれません。

というわけで、より環境を把握しておくためにも、現在、動作しているプロセス(コマンド)が 32 bit または 64 bit バイナリなのかを簡単に確認する方法をご紹介したいかと思います。
debugger を使いプロセスに attach して解析とか、truss でシステムコールを追いかけたりする必要もありません。

・Proc Tools を使ってみる


Solaris には、process filesystem (procfs) と呼ばれるプロセスの状態を記録する特別なファイルシステムが提供されています。

man -s 4 proc

この procfs を利用し、プロセスの動作をより視覚化するために proc tools なるものがが提供されています。
今回は、Proc Tools に含まれる pldd とコマンドを利用します。

man -s 1 proc

pldd は、動作中のプロセスが dlopen(3C) 関数を使用して呼び出している共有ライブラリを確認するために利用しますが、この共有ライブラリを確認することで、そのプロセスが 32 bit または 64 bit アプリケーションかを確認することができます。
※1 pldd は、出力を得るために、実行中のプロセスを内部的に一次停止させます。ご利用は計画的に。

その前に、Solaris における 64 bit サポートについては、次のようなお約束があります。

・32 bit オブジェクトと 64 bit オブジェクトを混在できない

このことから、32 bit アプリケーションは、32 bit ライブラリを呼び出し、64 bit アプリケーションは、64 bit ライブラリを呼び出しているはずです! というわけで、実際に見てみましょう。
例えば、稼働中の apache (http) のプロセスに pldd を実行してみます。

# ps コマンドで、http のプロセス ID を確認
# pldd 2861
2861: /usr/apache2/bin/httpd -k start
/usr/lib/libz.so.1
/usr/sfw/lib/libssl.so.0.9.7
/usr/sfw/lib/libcrypto.so.0.9.7
/lib/libdl.so.1
/usr/apache2/lib/libaprutil-0.so.0.9.16
/usr/apache2/lib/libexpat.so.0.1.0
/usr/apache2/lib/libapr-0.so.0.9.16
/lib/libsendfile.so.1
/lib/librt.so.1
/lib/libm.so.2
/lib/libsocket.so.1
/lib/libnsl.so.1
/lib/libresolv.so.2
/lib/libpthread.so.1
/lib/libc.so.1
:
このように、呼び出しているライブラリを確認することができます。
Solaris では、ライブラリやコマンド類が配置されるディレクトリには、通常 32 bit オブジェクトが配置(※2)さ­れますが、そこを更に堀下がって sparcv9 (SPARC版) または、amd64 (x86版) という、特別な名前がつけられたディレクトリに 64 bit オブジェクトが格納されます。
このようにディレクトリを分けることで 32 bit と 64 bit オブジェクトが混在することを防いでいます。
この例では、amd64 や sparcv9 の文字が見えないので、このプロセスは 32 bit アプリケーションであることがわかります。

※2 最近は、32 bit オブジェクトも i86 (x86 版) または sparcv7 (SPARC 版) という特別なディレクトリに配置されているものも増えており、��位のディレクトリにも同様のコマンドが配置されている場合があります。
例えば、dtrace コマンドなどがそうです。
$ find / -name dtrace -print
/usr/sbin/amd64/dtrace
/usr/sbin/i86/dtrace
/usr/sbin/dtrace
このように 3 つの dtrace コマンドが存在します。 それぞれのファイルサイズを見ると、/usr/sbin/dtrace だけが小さなファイルであることに気づきます。
$ ls -l ./usr/sbin/dtrace
-r-xr-xr-x 66 root bin 5816 Jan 9 2007 ./usr/sbin/dtrace\*
$ ls -l ./usr/sbin/i86/dtrace
-r-xr-xr-x 1 root bin 41264 Aug 15 2007 ./usr/sbin/i86/dtrace\*
$ ls -l ./usr/sbin/amd64/dtrace
-r-xr-xr-x 1 root bin 48520 Aug 15 2007 ./usr/sbin/amd64/dtrace\*
これは、/usr/sbin/dtrace は、コマンドの実態ではなく、i86 また amd64 に配置される dtrace コマンドの実態を呼び出すための wrapper コマンドとなるためです。

wrapper となる /usr/sbin/dtrace が行うことは、sysinfo(2) システムコールを利用して、システムが 32 bit または 64 bit kernel のどちらかで動作しているかを確認し、適切なバイナリを実行させるようにしています。
truss コマンドを使って、注意深く見てみるのもおもしろいかと思います。

では、試しに、64 bit アプリケーションのプロセスを見みてみましょう。
#例では、iSCSI target daemon を利用しています。これも dtrace 同様 wrapper が提供されています。­
# pldd 15531
15531: /usr/sbin/iscsitgtd
/lib/sparcv9/libumem.so.1
/lib/sparcv9/libuuid.so.1
/usr/lib/sparcv9/libxml2.so.2
/lib/sparcv9/libsocket.so.1
/lib/sparcv9/libnsl.so.1
/lib/sparcv9/libdoor.so.1
/lib/sparcv9/libavl.so.1
/lib/sparcv9/libmd5.so.1
/lib/sparcv9/libadm.so.1
/lib/sparcv9/libefi.so.1
/lib/sparcv9/libiscsitgt.so.1
/lib/sparcv9/libzfs.so.2
/lib/sparcv9/libaio.so.1
/lib/sparcv9/libc.so.1
/lib/sparcv9/libpthread.so.1
/usr/lib/sparcv9/libz.so.1
/lib/sparcv9/libm.so.2
/lib/sparcv9/libscf.so.1
/lib/sparcv9/libdevinfo.so.1
/lib/sparcv9/libdevid.so.1
/lib/sparcv9/libgen.so.1
/lib/sparcv9/libnvpair.so.1
/lib/sparcv9/libuutil.so.1
/lib/sparcv9/libsec.so.1
/platform/sun4u/lib/sparcv9/libc_psr.so.1  

sparcv9 ディレクトリに配置される共有ライブラリが呼び出されていることがわかり、このプロセスは、64 bit アプリケーションであることがわかります。
このように、呼び出されているライブラリから、動作中のプロセスが 32 bit か 64 bit アプリケーションかを判断することができますが、これでどうでしょうか?!

また、proc tools には、pldd 以外にも使えるツールがそろっていますので、ぜひ、利用してみてください。  
 

Join the discussion

Comments ( 2 )
  • guest Sunday, March 30, 2008

    pmap でプロセスのアドレス空間を見る方法では、確実とは言えませんかね?(笑)


  • moridenki in Sun Sunday, March 30, 2008

    おお、なるほど pmap だとアドレス空間の文字列が長いから!で判断できますね(笑

    --

    32 bit

    # pmap 952

    952:

    ksh

    08045000 12K rw--- [ stack ]

    08050000 184K r-x-- /usr/bin/ksh

    0808E000 4K rw--- /usr/bin/ksh

    64 bit

    # pmap 15531

    15531: /usr/sbin/iscsitgtd

    0000000100000000 176K r-x-- /usr/sbin/sparcv9/iscsitgtd

    000000010012C000 56K rwx-- /usr/sbin/sparcv9/iscsitgtd

    000000010013A000 24K rwx-- [ heap ]

    --

    また、pflags で data_model を確認するのも有効な手段ですね。

    --

    32 bit (は、_ILP32 と表示)

    # pflags 6353

    6353: /usr/apache2/bin/httpd -k start

    data model = _ILP32 flags = ORPHAN|MSACCT|MSFORK

    /1: flags = ASLEEP

    64 bit (は、_LP64 と表示)

    # pflags 15531

    15531: /usr/sbin/iscsitgtd

    data model = _LP64 flags = ORPHAN|MSACCT|MSFORK

    --

    pldd から、 pmap, pflags にまでお話が広がりました。コメントありがとうございました。


Please enter your name.Please provide a valid email address.Please enter a comment.CAPTCHA challenge response provided was incorrect. Please try again.Captcha