おじさんOS講座(1):pmapを使ってみよう
Saturday, March 8, 2008
勝手に開催してみた。おじさんOS講座。
といっても。私めは、OSの専門家でもなんでもない。また、母国語がUNIXではない。母国語のOSは、個人で飼育するのは、無理!なので、仕方なく家ではUNIXを飼ってます。
で、自分の、当時プログラマだった時代に、当然知ってるべきだったことを、UNIX語で、話そうかなあ、という企画です。ま、私めが、チョッとマジメに、UNIX語を、勉強してみようかなあと、思った感じです。
OSを意識せずにUNIXを使って生活している、最近の若いもんに、渇をいれようかなというのもありますが。
いつまで続くかわかりませんが、
第1回、pmapを使ってみよう
以下をとりあえずクリックして、別ウィンドウでみながら、解説をよんどくれ。
プログラムはこれ。
で、実行結果はこれ。
PMAPコマンドの出力はこれ。
プログラムの動作は、
1.各種のメモリーを確保します。順に、
gaibu 15M の初期化なし外部変数
gaibu2 25Mの初期化つき外部変数
jidou 30Mのオート変数
s 40Mの初期化あり関数内static変数
s2 50Mの初期化あり関数内static変数
*malloc_pointer 60Mのmallocした領域
2.上記で定義した各種変数のアドレスを表示して、
3.ついでに、main関数と、printf関数のポインターを表示しています。
以下解説。
1.08049000から始まる領域が、Private領域で、約75M消費されています。
確保した領域のサイズで推測できますが、プログラムの実行結果からもわかります。
これは、gaibu2と、s2の、初期化つきの、静的変数ですね。
Mapped Fileが、a.outになっています。これは、初期化しているので、プログラムの実行モジュール
から読み込む必要があります。で、
ls -l してみると、
-rwxr-xr-x 1 tanaka tanaka 78648971 3 8 14:25 a.out
プログラムが75M以上使用しているのがわかりますね。
2.0CB49000から始まる領域が、同様に約55M使用されています。
これは、同様に、gaibuと、sの、初期化していない、静的変数ですね。
プログラムが実行されるときに、OSに対し、「0で初期化して、55Mのメモリーをよこせ。」
とすることができる(初期化していないので)ので、プログラムの実行モジュールのサイズには
ふくまれていません。
3.28200000からは、60Mのmallocした領域が確保されています。
これは、ヒープといいます。(freebsdでは、anonymousの表示ですが。)
4.BDDE0000からは、30Mの、オート変数の領域が確保されています。
これは、スタックといいます。(freebsdでは、同様にanonymousの表示。)
5.プログラムの実行結果の、main関数と、printf関数のアドレスは、08048000から始まる領域
にあります。a.outにマップされています。
mainは、a.outにマップされているのはわかるが、なぜ、printfも同様の場所にあるのでしょうか。
printfは、2807D000から始まる、libc.soからマップされている領域にあってもよさそうなものかと。
これは、次回の話題にしますが、printfのプログラムコードの実体は、2807D00からの領域に
あります。private memoryは消費していず、sharedの属性がついているのがわかりますね。
また、書き込みできない領域になっています。( r-xでwがついてない)
libc.soを使用している他のプログラムと、この領域は最終的には共有されています。また、
この領域には書き込み禁止になっていて、この領域に書き込むには、(UNIXはどうかわかりませ
んが)おそらく、OSの深部に突入することができる、、、てな権限が必要でしょうね。
まあ、unixは、モノシリックカーネル、で、このあたりの管理はあいまいで、階層化されている
わけじゃない、、、んだとは思いますが、少なくとも、この領域に書き込もうとすると、ちゃんと、
OSがエラーを通知してくれるものだと思います。
とまあこんなもんですが、以下、つれずれ、思うことを書きます。
1.今回、上記のようなことをやって、コンパイルオプションを何もつけずに、プログラムになんの
工夫もせずに、こんな検証ができてしまったことは、正直、驚きです。
なにかというと、こんなプログラムだったら、コンパイラーのオプティマイザーが働いて、
結局なんのメモリー検証もできないような実行結果になるべきだ!
ということなんですが、、、UNIXや、gccって所詮、こんなもんなんだろーなあー。
2.外部変数と、静的内部変数は、違うセグメントにとってくれたほうが、デバッガーとか、いろいろと
考えると便利な気がするんですけど、、、なんで同じ領域にとられるんでしょうね。手抜き?
3.04048000から始まる領域の、r-x のa.outのプログラム命令が格納される部分と、
04049000から始まる変数を管理している領域の rwxのところが、表示上ダブっています。
おそらく、04048000から始まって、10000 (16進なので65K) の領域に、プログラム命令が
格納されているということでしょう。
4.1の領域が、private memoryを消費しています。sharedじゃない。
UNIXは、こんなものなのか、なんか指定の方法があるのか、あくまで表示上の問題なのか、
わかりませんが、これが意味することは、
シェアードオブジェクトにしていない、プログラム実行モジュールの本体に格納された命令は、
プロセス間で、共有されない。
ということを意味しています。これは、次のうちどちらなんでしょうね。
(1) 基本的に、unixのプログラムの、ソースコードが多い分は、シェアードオブジェクトに
しなきゃ、、、でないと、プロセスごとにそのメモリーは消費される。
(2) 実は、そんなことをしたい場合のために、実行モジュールを、OSにインストール
するようなコマンドがある。そのコマンドで、その実行モジュールをOSに意識させ
ると、実行モジュールの命令部分が、他のプロセスと共有することができる。
(3) あくまで、pmonの表示上の問題で、実際は共有されている。
おそらく(1)か(3)かと思いますが、、、そのどちらかは、実際にメモリーを凶悪に命令部分
で共有するようなプログラムを複数動かしてみればわかるんでしょうけど。
で、これを読んでくれてる、心当たりのある人に宿題!
freebsdのメモリセグメントのとられかたは、上記に書きましたが、linuxはどう?solarisはどう?
aixはどうなの?
上記に書いた、実行モジュールをOSにインストールするようなことって、UNIXはできないの?
期待せずに待ってます。
******3月10日追記**********
gccのデフォルトは、オプティマイズしない、、、だったのね。
てっきりオプティマイズがデフォルトだと思ってたのは、母国語のOSがそうだったからだけど。
#でも、こうやって、ブログで、断言して、偉そうなこと、書くのは、勉強になるなあ。
#ちょっと調べないと、書けないし、
#調べても、間違ってること後から気づくし、うまくいけば、人に指摘してもらえるし。
といっても。私めは、OSの専門家でもなんでもない。また、母国語がUNIXではない。母国語のOSは、個人で飼育するのは、無理!なので、仕方なく家ではUNIXを飼ってます。
で、自分の、当時プログラマだった時代に、当然知ってるべきだったことを、UNIX語で、話そうかなあ、という企画です。ま、私めが、チョッとマジメに、UNIX語を、勉強してみようかなあと、思った感じです。
OSを意識せずにUNIXを使って生活している、最近の若いもんに、渇をいれようかなというのもありますが。
いつまで続くかわかりませんが、
第1回、pmapを使ってみよう
以下をとりあえずクリックして、別ウィンドウでみながら、解説をよんどくれ。
プログラムはこれ。
で、実行結果はこれ。
PMAPコマンドの出力はこれ。
プログラムの動作は、
1.各種のメモリーを確保します。順に、
gaibu 15M の初期化なし外部変数
gaibu2 25Mの初期化つき外部変数
jidou 30Mのオート変数
s 40Mの初期化あり関数内static変数
s2 50Mの初期化あり関数内static変数
*malloc_pointer 60Mのmallocした領域
2.上記で定義した各種変数のアドレスを表示して、
3.ついでに、main関数と、printf関数のポインターを表示しています。
以下解説。
1.08049000から始まる領域が、Private領域で、約75M消費されています。
確保した領域のサイズで推測できますが、プログラムの実行結果からもわかります。
これは、gaibu2と、s2の、初期化つきの、静的変数ですね。
Mapped Fileが、a.outになっています。これは、初期化しているので、プログラムの実行モジュール
から読み込む必要があります。で、
ls -l してみると、
-rwxr-xr-x 1 tanaka tanaka 78648971 3 8 14:25 a.out
プログラムが75M以上使用しているのがわかりますね。
2.0CB49000から始まる領域が、同様に約55M使用されています。
これは、同様に、gaibuと、sの、初期化していない、静的変数ですね。
プログラムが実行されるときに、OSに対し、「0で初期化して、55Mのメモリーをよこせ。」
とすることができる(初期化していないので)ので、プログラムの実行モジュールのサイズには
ふくまれていません。
3.28200000からは、60Mのmallocした領域が確保されています。
これは、ヒープといいます。(freebsdでは、anonymousの表示ですが。)
4.BDDE0000からは、30Mの、オート変数の領域が確保されています。
これは、スタックといいます。(freebsdでは、同様にanonymousの表示。)
5.プログラムの実行結果の、main関数と、printf関数のアドレスは、08048000から始まる領域
にあります。a.outにマップされています。
mainは、a.outにマップされているのはわかるが、なぜ、printfも同様の場所にあるのでしょうか。
printfは、2807D000から始まる、libc.soからマップされている領域にあってもよさそうなものかと。
これは、次回の話題にしますが、printfのプログラムコードの実体は、2807D00からの領域に
あります。private memoryは消費していず、sharedの属性がついているのがわかりますね。
また、書き込みできない領域になっています。( r-xでwがついてない)
libc.soを使用している他のプログラムと、この領域は最終的には共有されています。また、
この領域には書き込み禁止になっていて、この領域に書き込むには、(UNIXはどうかわかりませ
んが)おそらく、OSの深部に突入することができる、、、てな権限が必要でしょうね。
まあ、unixは、モノシリックカーネル、で、このあたりの管理はあいまいで、階層化されている
わけじゃない、、、んだとは思いますが、少なくとも、この領域に書き込もうとすると、ちゃんと、
OSがエラーを通知してくれるものだと思います。
とまあこんなもんですが、以下、つれずれ、思うことを書きます。
1.今回、上記のようなことをやって、コンパイルオプションを何もつけずに、プログラムになんの
工夫もせずに、こんな検証ができてしまったことは、正直、驚きです。
なにかというと、こんなプログラムだったら、コンパイラーのオプティマイザーが働いて、
結局なんのメモリー検証もできないような実行結果になるべきだ!
ということなんですが、、、UNIXや、gccって所詮、こんなもんなんだろーなあー。
2.外部変数と、静的内部変数は、違うセグメントにとってくれたほうが、デバッガーとか、いろいろと
考えると便利な気がするんですけど、、、なんで同じ領域にとられるんでしょうね。手抜き?
3.04048000から始まる領域の、r-x のa.outのプログラム命令が格納される部分と、
04049000から始まる変数を管理している領域の rwxのところが、表示上ダブっています。
おそらく、04048000から始まって、10000 (16進なので65K) の領域に、プログラム命令が
格納されているということでしょう。
4.1の領域が、private memoryを消費しています。sharedじゃない。
UNIXは、こんなものなのか、なんか指定の方法があるのか、あくまで表示上の問題なのか、
わかりませんが、これが意味することは、
シェアードオブジェクトにしていない、プログラム実行モジュールの本体に格納された命令は、
プロセス間で、共有されない。
ということを意味しています。これは、次のうちどちらなんでしょうね。
(1) 基本的に、unixのプログラムの、ソースコードが多い分は、シェアードオブジェクトに
しなきゃ、、、でないと、プロセスごとにそのメモリーは消費される。
(2) 実は、そんなことをしたい場合のために、実行モジュールを、OSにインストール
するようなコマンドがある。そのコマンドで、その実行モジュールをOSに意識させ
ると、実行モジュールの命令部分が、他のプロセスと共有することができる。
(3) あくまで、pmonの表示上の問題で、実際は共有されている。
おそらく(1)か(3)かと思いますが、、、そのどちらかは、実際にメモリーを凶悪に命令部分
で共有するようなプログラムを複数動かしてみればわかるんでしょうけど。
で、これを読んでくれてる、心当たりのある人に宿題!
freebsdのメモリセグメントのとられかたは、上記に書きましたが、linuxはどう?solarisはどう?
aixはどうなの?
上記に書いた、実行モジュールをOSにインストールするようなことって、UNIXはできないの?
期待せずに待ってます。
******3月10日追記**********
gccのデフォルトは、オプティマイズしない、、、だったのね。
てっきりオプティマイズがデフォルトだと思ってたのは、母国語のOSがそうだったからだけど。
#でも、こうやって、ブログで、断言して、偉そうなこと、書くのは、勉強になるなあ。
#ちょっと調べないと、書けないし、
#調べても、間違ってること後から気づくし、うまくいけば、人に指摘してもらえるし。
コメントする
トラックバック
この記事へのトラックバックURL:
これまでに受信したトラックバックはありません。