次の手順は、スレッドアナライザでマルチスレッドプログラムの問題を解決するプロセスを示しています。
データの競合の検出を行う場合、プログラムを計測します。
データの競合の検出またはデッドロック検出の実験を作成します。
実験結果を検討し、スレッドアナライザで明らかになったマルチスレッドプログラミングの競合が、正当なバグまたは影響のない現象であるかどうかを判断します。
本物のバグを修正し、入力データ、スレッド数、ループスケジュール、さらにはハードウェアなど、さまざまな要素を変更しつつ追加実験 (前述の手順 2) を作成します。これを繰り返すことで、決定論的ではない問題の突き止めに役立ちます。
前述の手順 1 から 3 については、以降の節で説明します。
データの競合を検出するには、次の 3 つの手順を実行する必要があります。
データの競合の検出を有効にするコードを計測する
計測したコードで実験を作成する
データの競合の実験結果を検討する
アプリケーションでデータの競合の検出を可能にするには、実行時にメモリーアクセスを監視するコードをあらかじめ計測しておく必要があります。コードの計測方法としては、コンパイル中にアプリケーションのソースレベルで行う場合もあれば、バイナリに対し追加ツールを実行することによってアプリケーションのバイナリレベルで行う場合もあります。
ソースレベルの計測は、コンパイルに特別なオプションを指定して行います。また、使用する最適化レベルおよびその他のコンパイラオプションを指定できます。ソースレベルの計測は、コンパイラが一部の分析と計測を少ないメモリーアクセスで行うことができるため、実行時間がより短縮されます。
バイナリレベルの計測は、ソースコードが使用できない場合に役立ちます。ソースコードがある場合でもバイナリ計測を使用することがあります。ただしこの場合、アプリケーションが使用している共有ライブラリはコンパイルできません。discover ツールを使用したバイナリ計測では、バイナリだけでなく、開かれている共有ライブラリすべてを計測します。
ソースレベルで計測するには、特別なコンパイラオプションを付けてソースコードをコンパイルします。
-xinstrument=datarace |
このコンパイラオプションを付けてコンパイラで生成されたコードが、データの競合の検出用に計測されます。
-g コンパイラオプションも、アプリケーションバイナリの構築時に使用する必要があります。このオプションを付けると、スレッドアナライザでデータの競合を報告するときにソースコードおよび行番号情報を表示するための追加データを生成できます。
バイナリレベルで計測するには、discover ツールを使用する必要があります。バイナリが a.out という名前の場合、次のように実行することによって、計測済みのバイナリ a.outi を作成できます。
discover -i datarace -o a.outi a.out |
discover ツールでは、開かれている共有ライブラリを、それがプログラム内で静的にリンクされているか、dlopen() によって動的に開かれているかにかかわらず、すべて自動的に計測します。デフォルトで、ライブラリの計測済みコピーは、ディレクトリ $HOME/SUNW_Bit_Cache に書き込まれます。
有効な discover コマンド行オプションの一部を次に示します。詳細は、discover(1) のマニュアルページを参照してください。
計測済みバイナリを、指定したファイル名で出力する
指定したライブラリを計測しない
どのライブラリも計測しない
キャッシュディレクトリを dir に変更する
データの競合を検出するためにプログラムのバイナリコードを計測する場合、discover ツールでは、入力バイナリを次の条件を満たしてコンパイルする必要があります。
オペレーティングシステムのバージョンが、少なくとも Oracle Solaris 10 Update 5 または OpenSolaris version snv_70 である。
コンパイラが Oracle Solaris Studio 12 Update 1 以降のリリースである。
コンパイラ最適化フラグ (-xO1、-xO2、-xO3、-xO4、-xO5) のいずれかを使用している。
データの競合の報告時にスレッドアナライザがソースコードと行番号情報を表示できるように、-g コンパイラオプションも使用する必要がある。
また、バイナリがコンパイラオプション -xbinopt=prepare を付けてコンパイルされた場合は、SPARC ベースのシステムで実行中の、以前の Solaris バージョンでも discover ツールを使用できることがあります。このコンパイラオプションについては、cc(1)、CC(1)、または f95(1) のマニュアルページを参照してください。
データの競合の検出実験を作成するには、-r race フラグを付けて collect コマンドを使用して、アプリケーションを実行し、プロセスの実行中に実験データを収集します。-r race オプションを使用すると、競合を起こしたデータアクセスの対を収集データから知ることができます。
データの競合を検出する実験を検討するには、tha コマンドを使用します。このコマンドにより、スレッドアナライザのグラフィカルユーザーインタフェースが起動します。er_print コマンド行インタフェースも使用できます。
デッドロックの検出には、次の 2 つの手順が必要です。
デッドロック検出実験の作成
デッドロック実験結果の検討
デッドロック検出実験を作成するには、-r deadlock フラグを付けて collect コマンドを使用して、アプリケーションを実行し、プロセスの実行中に実験データを収集します。-r deadlock オプションを使用した場合、巡回チェーンを構成するロックの保持とロックの要求が収集データに含まれます。
デッドロックを検出する実験を検討するには、tha コマンドを使用します。このコマンドにより、スレッドアナライザのグラフィカルユーザーインタフェースが起動します。er_print コマンド行インタフェースも使用できます。
データの競合とデッドロックを同時に検出するには、「1.4.1 データの競合を検出するための使用モデル」で説明した 3 つの手順に従いデータの競合を検出し、-r race,deadlock フラグを付けた collect コマンドでアプリケーションを実行します。これで競合検出とデッドロック検出の両方のデータが実験結果に含まれます。