IT・技術研修ならCTC教育サービス

サイト内検索 企業情報 サイトマップ

研修コース検索

コラム

Windows/Linuxの実践トラブルシューティング

CTC 教育サービス

 [IT研修]注目キーワード   OpenStack  OpenFlow/SDN  情報セキュリティ  Python  システムトラブルシュート 

第12回 プログラムを調べる(メモリダンプの取得、解析方法)その3 (加賀結衣) 2017年6月

こんにちは。加賀結衣(かが ゆい)と申します。

このコラムでは、株式会社リックテレコムの「Windows/Linuxのトラブル追跡実践ノウハウ」をもとに、私が実際にPCに触りながら学んだことをまとめていきます。
コラム内のページ表記は、この書籍のページを示します(Pはページです)。
日々発生するコンピュータのトラブルに対し、どのようなツールを使い、どのような情報を収集すればよいか知りたいと思われている初心者の方に、このコラムが少しでもお役に立てば嬉しいです。

今回は、引き続き第4章 「プログラムを調べる」の「4.3 Linux編 4.3.7」以降を確認していきましょう。メモリダンプの取得、解析方法について学びます。

---------------------------------------------------------------------

第4章 プログラムを調べる
4.3 Linux編
 4.3.7 シンボルを調べる(p.233)
 4.3.8 Linuxの実行ファイルのライブラリ依存関係を調べる(p.236)
 4.3.9 proc下のプロセスの情報を取得する(p.238)

4.4 Linux編(メモリダンプの調査)
 4.4.1 クラッシュしたプロセスのダンプファイルの調査をする(P.242)
 4.4.2 実行中のプロセスの強制ダンプを行う(P.246)

----------------------------------------------------------------------

 

 4.3.7 シンボルを調べる(p.233)

ライブラリとは、プログラムのパーツのようなもので、頻繁に使用される機能をまとめて他のプログラムから利用できるようにしたものですが、nmコマンドではこのライブラリや実行ファイルが持っているシンボル・テーブルを表示することができます。
nmコマンドの出力結果は、シンボルのアドレス(メモリ上の位置)、シンボルのタイプ、シンボル名の順に出力されます。

シンボルのタイプは、アルファベットで次のように表現されます。
シンボルにはグローバル・シンボルとローカルシンボルがあり、外部参照可能なものをグローバル・シンボルと言います。
それぞれのシンボル・タイプに対応する意味を見ていきましょう。

A (グローバル)絶対シンボル
a (ローカル)絶対シンボル 
B (グローバル)bss シンボル 
b (ローカル)bss シンボル 
D (グローバル)データ・シンボル 
d (ローカル)データ・シンボル 
T (グローバル)テキスト・シンボル 
t (ローカル)テキスト・シンボル 
U 未定義シンボル

未定義シンボルのみを表示させたい場合、-u を用いて nm -u オブジェクトファイル名、動的シンボルを表示させたい場合、-D もしくは --dynamic を用いて nm -D オブジェクトファイル名(もしくは nm --dynamic オブジェクトファイル名)と指定すると表示させることができます。

例えば、オブジェクトファイル名を a.out としますと、nm -u a.out やnm -D a.outのように指定します。

このようなnmコマンドは、例えば、プログラムが使用しているライブラリが古くて、プログラム側が呼び出した関数とライブラリ側の関数とが合致せず不整合が発生する場合などに役に立ちます。

 

 4.3.8 Linuxの実行ファイルのライブラリ依存関係を調べる(p.236)

共有ライブラリの依存関係を確認したい場合には、lddコマンドを利用します。
ldd -v プログラムのパス、という書式でライブラリの依存関係を表示させることができます。
例えば、パスを /bin/ls としますと、ldd -v /bin/ls のように指定します。

なお、ライブラリには、共有ライブラリと静的ライブラリがあり、前者は、/libや/use/libなどにおかれます。
共有ライブラリはプログラムの実行時にロードされ、複数のプログラム間で共有されます。

一方、後者の静的ライブラリは、プログラムの作成時にその実行ファイル内に埋め込まれるものです。

プログラムが、ライブラリの機能(関数)を呼び出すことにより計算や制御といった基本機能以外の機能を利用することをリンクといいます。このうち、コンパイルする時点で、コンパイラがライブラリから機能を取り出し、それを実行ファイル内に埋め込んでおくことを静的リンク(スタティック・リンク)といいます。

このように、 実行ファイル内にライブラリの機能を埋め込むと、バージョン間の互換性を気にしなくてよい反面、よく使われるライブラリの機能は、さまざまな実行ファイル内に重複することになります。また、実行可能形式のプログラムサイズが大きくなってしまいます。

これを避ける目的で、コンパイル時には実行ファイルに機能を埋め込まず、意図的に不揃いにしておき、実行時にリンクすることを、動的リンク(ダイナミック・リンク)といいます。

実行ファイルをダウンロードして使おうとすると、必要な共有ライブラリがないため実行できないことがありますが、lddコマンドでは、プログラム実行時にリンクされる共有ライブラリのリストを表示することができます。
これにより、どのライブラリを新たにインストールしなくてはならないのかを、判断することができます。

 

 4.3.9 proc下のプロセスの情報を取得する(p.238)

/proc ディレクトリには、システムリソースやプロセス情報が配置されています。
/proc は cat コマンドなどで一般のファイルと同様に読み出すことができます。

ls -l /pro/プロセスID/fd で、プロセスが開いているファイルを確認することができます。

プロセスIDディレクトリにある、cmdline、cwd、exeを見ることで、そのプロセスのコマンドラインのパスや、現在の作業ディレクトリ、ルートディレクトリなどを確認することができます。
また、environにては、対象プロセスの環境変数を確認することができます。

environ内はヌルバイトで区切られているため、中身を確認するには strings コマンドを利用します(catコマンドなどでは表示させることができません)。

 

- 参考情報

/procによるLinuxチューニング [前編]
~ /procで理解するOSの状態 ~
http://www.atmarkit.co.jp/flinux/special/proctune/proctune01a.html

/procによるLinuxチューニング [前編]
~ /procで理解するOSの状態 ~
http://www.atmarkit.co.jp/flinux/special/proctune/proctune01b.html

 

4.4 Linux編(メモリダンプの調査)

 4.4.1 クラッシュしたプロセスのダンプファイルの調査をする(P.242)

プログラムがクラッシュした場合、ダンプファイルを調査することでたくさんの情報を得ることができる場合があります。

ulimitコマンドは、コマンドに割り当てる資源を制限することができるコマンドですが、ulimit -a で、割り当てられている各種資源の制限内容を表示することができます。

fig01

 

ulimit -a の出力結果で上記のように core file size が0である場合、このままではダンプファイルを出力することができないため、-cオプションを使ってダンプファイルの容量を変更します。

例えば、ulimit -c 1000000 などと指定します。

取得したダンプファイルの調査には gbd コマンドを使用します。
gdb プログラム ダンプファイル、という形式で指定することで、ダンプファイルを解析することができます。

gdb の起動後、btコマンドを実行すると、ダンプを取得した瞬間のプログラムが動作していた場所の階層情報であるバックトレースを取得することができます。

 

- 参考情報

【 ulimit 】 コマンドに割り当てる資源を制限する
http://itpro.nikkeibp.co.jp/article/COLUMN/20060227/230911/

 

 4.4.2 実行中のプロセスの強制ダンプを行う(P.246)

前記のgdbはGnu DeBugger の略称で、コンパイルしたプログラムのデバッグを支援するデバッガです。
実行中のプロセスのメモリダンプを安全に取得するには、このgdbが役に立ちます。

$ gdb
(gdb) attach PID
(gdb) gcore core
(gdb) detach

gdbが起動すると、(gdb)の文字列から始まるインタラクティブな入力状態になります。

まず attach コマンドで PID を指定して実行中のプロセスにアタッチします。
次に、 gcore コマンドで core ファイルを生成します。
出力先のダンプファイルを引数で与えて指定すると、ダンプファイルが作成されます。
そして最後に、quitコマンドでgdbを終了します。

 

今日のまとめ

★nmコマンドでは、ライブラリや実行ファイルがもつシンボル・テーブルを表示できます。

★lddコマンドでは、プログラム実行時にリンクされる共有ライブラリのリストを表示することができます。

★ulimitコマンドは、コマンドに割り当てる資源を制限したり拡張したりすることができます。

 

なお、サーバ(OS)・ネットワーク分野における原因究明の仕方や切り分けなどを行う方法を基礎から学びたい方には、CTC教育サービスのオリジナルコースである「システムトラブルシュート(ファーストステップ)」「システムトラブルシュート(ネクストステップ)」がお勧めです。
詳細は、以下のリンクをご参照くださいませ。
http://www.school.ctc-g.co.jp/course/SSE01.html
http://www.school.ctc-g.co.jp/course/SSE02.html

最後まで読んでくださってどうもありがとうございました。次回もどうぞお楽しみに。

 


 

 [IT研修]注目キーワード   OpenStack  OpenFlow/SDN  情報セキュリティ  Python  システムトラブルシュート