ウェブサイト検索

ltraceを使用してライブラリ呼び出しをトレースする方法


Linuxでクールな新しいプログラムをインストールする際に観察されるライブラリエラーやバグを修正することに興味がありますか?ライブラリコールをデバッグするのに必要なツールを提供するltraceの使い方を示したこの記事をチェックしてください。

ライブラリとは何ですか?

ほとんどの人は知っています

.dll/.DLL

Windowsのファイル(ダイナミックリンクライブラリ)。Linuxの同等品は

.so

ファイル、共有オブジェクト、一般にライブラリと呼ばれます。

ライブラリは、アプリケーションによって利用されることができ、プログラムがそのプログラムコードの外部から機能を利用できるようにします。例えば、ウェブサーバーは、オペレーティングシステムのベンダーや他のサードパーティによって書かれたディスクI/Oライブラリを使用したいと考えるかもしれません。これは、ほとんどすべてのオペレーティングシステムにおいて、共通の利益や資源を共有する方法です。

ライブラリは、実行時に動的にロードされることも(呼び出しプログラムが起動している時など)、ターゲットアプリケーションやバイナリにコンパイルされることもあります。したがって、常に使用されるかどうかに関わらず、コンパイルまたはビルドされたアプリケーションが起動されるたびにロードされます。

ライブラリ、その依存関係、そしてlddツールについてさらに学ぶには、Linuxでの共有オブジェクト依存関係の扱い方について読むと良いでしょう。lddツールは、より高度なLinuxユーザーのツールボックスにおいて、もう一つ便利なツールです。

ltrace とは何ですか?

Linuxには、システムコールや信号を追跡するためのstraceのようなさまざまなトレースユーティリティがあります。

traceroute

ネットワークルーティングを追跡するために。ltraceユーティリティ/ツールはすべてのライブラリ呼び出しを追跡します。

もし、上記のリンクにある私たちの「Linuxにおける共有オブジェクト(ライブラリ)依存関係について」の記事を読んでいれば、特定のバイナリがどのライブラリにリンクされているかをlddツールを使って調べる方法をすでに知っているでしょう。ltraceの目的と機能はやや異なります; より多くはそのラインに沿って

strace

, ltraceコマンドは、特定のプログラムが実行中に行っているすべてのライブラリ呼び出しを追跡します。

似ている

strace

, プログラムを 下に(階層のように考えてください)ltrace で開始できます。ltrace が開始するプログラムを最初のオプションとして指定するだけで、ltrace はそのプログラムを私たちのために起動し、すぐに(より高いレベルで)オペレーティングシステムやサードパーティがインストールしたライブラリへのすべての呼び出しを追跡し始めます。

それは、実行中のプログラムによって行われる ダイナミック ライブラリ呼び出しを遮断して記録することによって行われます。また、実行中のプログラムに送信される信号も追跡します。これは非常に似ています。

strace

(そして、もし望むのであれば、この機能は指定することによって無効にできます)

-b

または同等のもの

--no-signals

ltraceのオプション。

ここで「動的」という用語は非常に重要であることに注意してください;ltraceは外部ライブラリへの呼び出しをトレースします(形式として

.so

または

.a

ファイル)、すなわちプログラムに直接コンパイルされていないライブラリ;動的ライブラリ。したがって、静的(コンパイルされた)ライブラリを持つバイナリがある場合、ltraceはその内部呼び出しを見ることができず、トレースすることができません。

ltraceのインストール

Debian/AptベースのLinuxディストリビューション(UbuntuやMintなど)にltraceをインストールするには、ターミナルで以下のコマンドを実行してください:

sudo apt install ltrace

RedHat/YumベースのLinuxディストリビューション(RHEL、CentOS、Fedoraなど)にltraceをインストールするには、ターミナルで次のコマンドを実行します:

sudo yum install ltrace

ltraceを使用する

小さなテスト環境を設定しましょう:

sudo apt install tar xz-utils

mkdir ~/workspace && cd ~/workspace

touch a b c

ここでは、xz-utilsをインストールすることで、tarとxzをインストールしました(CentOS/RHEL/Fedoraを使用している場合は、sudo yum install tar xzを使用できます)。次に、~/workspaceというディレクトリを作成し、その中に移動しました。それから、touchコマンドを使って、ファイルa、b、cの3つの空のファイルを作成しました。

まず、私たちの3つのファイルを(tar 結合し、xz 圧縮された)archive.tar.xz アーカイブに圧縮し、その実行をltraceの下で行い、ltraceの出力を観察しましょう:

ltrace tar -hcf --xz archive.tar.xz *

出力は少量しか見えませんが、プログラムが正常に終了したことが確認できます(アーカイブファイルが作成されました)。つまり、status 0:Linuxでは、0の終了コードは常に成功を意味します(ただし、プログラムは終了コードが正しく実装されている必要があります)。

これは今のところあまり役に立ちません。tarがここでどのように動作するかを数秒間考えると、すぐに私たちの次のアプローチが明らかになります。熱心な読者は、tarコマンドが内部でxzコマンドを呼び出すことを理解しているかもしれません。私たちのtarコマンドラインに渡された--xzオプションは、圧縮にxzプログラムが使用されることを保証します。

二次プロセス(または全体の階層での第三のプロセス)であるxz(階層:ltrace > tar > xz)は、必要に応じてtarによって開始されます。そのため、私たちはltraceの下で実行されているプログラム、つまりtarの子プロセスを追跡する必要があります。これを行うには、ltraceに-fオプションを指定します:

ltrace -f tar -hcf --xz archive.tar.xz *

注意すべきことは、tarの後ではなく、ltraceのすぐ後に-fオプションを指定することが重要だということです。その理由は、-fオプションをtarコマンドではなく、ltraceに指定したいからです。tarコマンドの後のすべてのオプションはtar特有のオプションであり、-fはltrace特有のオプションです。

出力は少し興味深くなっています。まだライブラリ呼び出し(いかなる形でも)を観察していませんが、少なくとも二つのサブプロセスがフォークされていること(exec()に注目)と、どちらのサブプロセスもステータス0で終了していることがわかります。便利で良いことです。

それでは、私たちのライブラリコールはどこにありますか? tar と xz(アーカイブファイルを作成するためにコマンドが使用する二つのプログラム)を ldd でチェックすると、両方のプログラムが使用するほとんどのライブラリがシステムライブラリであることがすぐにわかります。

whereis tar

whereis xz

ldd /bin/tar

ldd /usr/bin/xz

したがって、ltraceに-Sオプションを指定することで、システムライブラリコールのトレースを有効にする必要があります。このオプションは、出力が少し冗長になるため、デフォルトでは無効になっています。また、システムライブラリは一般的に非常に安定していると想定されているため、最初からトレースする必要はないと考えられています。それでは、見てみましょう。

ltrace -fS tar -hcf --xz archive.tar.xz * 

または、テスト目的の場合:

ltrace -fS tar -hcf --xz archive.tar.xz * 2>&1 | head -n10

ltrace -fS tar -hcf --xz archive.tar.xz * 2>&1 | tail -n10

出力が膨大だったため、最初の10行と最後の10行を取得するために、headとtailコマンドを使用する必要がありました。これらのコマンドを使用するためには、ltraceがデフォルトでstderrに報告するため、stderrをstdoutにリダイレクトする必要がありました。具体的には、2>&1リダイレクションを使用しました。リダイレクションについてもっと学びたい場合は、Bashの自動化およびスクリプト基本(パート3)を参照してください。

今、-Sオプションを追加したので、アクセスされるすべてのライブラリを見ることができます。例えば、/etc/ld.so.preloadがアクセスされるのが見えます。出力は順次(上から下へ)表示されるため、その間に別のイベント(サブプロセスがフォークされるなど)があれば、これらは発生した瞬間にインラインで示されます。また、時間ベースの出力用に-tオプションを追加することもできます:

まとめる

この記事では、すべての動的ライブラリ呼び出しを追跡できる優れたツールである多用途のltraceプログラムを紹介し、議論しました。私たちはltraceをインストールし、テスト環境を整え、最も一般的に使用されるオプションを用いていくつかのltraceコマンドを実行しました。

関連記事: