Oracle Solaris Studio 12.4 Man Pages

印刷ビューの終了

更新: January 2015
 
 

tha(1)

名前

tha - スレッドアナライザ実験の解析用 GUI

形式

tha [ options ] [ thread-analyzer-experiment ]

説明

tha コマンドは、 collect (1) コマンドを使用してコレクタによって収集されたさまざまなスレッドアナライザ実験を解析するための GUI を呼び出します。この GUI は、スレッドアナライザ実験を検証するようにパフォーマンスアナライザをカスタマイズしたものです。

コレクタは、プロセスの実行中に、スレッドアナライザ実験を作成するためにスレッド分析情報を収集します。tha コマンドは、このような実験を読み込み、検出されたエラーを表示します。現在のスレッドアナライザは、データ競合の検出とデッドロックの検出をサポートしています。これらの詳細は、下記の「データ競合の検出」と「デッドロックの検出」のセクションを参照してください。

コマンド行バージョンの tha コマンドは er_print(1) ユーティリティーとして利用できます。

tha を起動するには、コマンド行で次のように入力します。

tha [thread-analyzer-experiment]

tha コマンドと analyzer(1) コマンドはどちらも、スレッドアナライザの実験を読み取るために使用できます。tha コマンドには、analyzer コマンドと同じ機能がありますが、デフォルトのタブはスレッドアナライザの実験に関連する一連のタブに簡略化されています。

オプション

-j | --jdkhome jvmpath

analyzer を実行するための Java[TM] 仮想マシン (JVM) ソフトウェアへのパスを指定します。デフォルトのパスは、JVM へのパスの環境変数を JDK_HOME、JAVA_PATH の順に検査することによって最初に取得されます。両方の環境変数が設定されていない場合、デフォルトパスは、Java[TM] 2 Platform, Standard Edition テクノロジが Oracle Solaris Studio リリースとともにインストールされた場所になります。インストールされていない場合は、ユーザーの PATH に設定された場所になります。(用語「Java 仮想マシン」および「JVM」は、Java(TM) プラットフォームの仮想マシンを意味します。)

-J jvm-option

JVM(TM) ソフトウェアオプションを指定します。

-f | --fontsize size

analyzer で使用するフォントサイズを指定します。

-v | --verbose

起動する前にバージョン情報と Java 実行時引数を出力します。

-V | --version

バージョン情報を出力して終了します。

-? | -h| --help

使用方法に関する情報を出力して終了します。

THA ウィンドウ -- 左側のタブ

THA ウィンドウ -- 左側のタブ

tha ウィンドウは、メニューバー、ツールバー、および各種表示のためのタブを含む分割ペインで構成されます。

左側のペインには、プリンシパル表示用のタブが含まれています。ペインに実際に表示されるタブは、.er.rc ファイルの rtabs 指令によって制御されます。「実験」タブは常に表示されます。「競合」タブは、1 つ以上のロードされた実験にデータの競合データが含まれている場合に表示されます。「デッドロック」タブは、1 つ以上のロードされた実験にデッドロックデータが含まれている場合に表示されます。「デュアルソース」タブは、「競合」タブまたは「デッドロック」タブのどちらかが表示されている場合に表示されます。

デフォルトでは、「競合」タブが選択されます (使用可能な場合)。「競合」タブが使用できない場合は、「デッドロック」タブが選択されます (使用可能な場合)。どちらも使用できない場合は、「実験」タブだけが表示されます。

「競合」タブ

「競合」タブは、1 つ以上のロードされた実験にデータ競合のデータが含まれている場合に表示されます。このタブには、アプリケーション内で検出されたデータ競合のリストが表示されます。デフォルトでは、データ競合のリスト内の最初のデータ競合が選択されます。

データ競合ごとに、次の情報が表示されます。

  • データ競合を識別する一意の ID。

  • データの競合に関連付けられた 1 つ以上の仮想アドレス (Vaddr)。データ競合が複数の仮想アドレスで発生した場合、単一のアドレスの代わりに「(複数のアドレス)」と表示されます。

  • データ競合を構成する 2 つの異なるスレッドによる 2 つのアクセス。アクセスごとに、アクセスの種類 (読み取りまたは書き込み) のほか、アクセスが行われたソースコード内の関数、オフセット、および行番号が表示されます。

  • データの競合に関連付けられたトレースの総数。個々のトレースは、「総トレース数」ラベルの左側のボタンをクリックすることにより表示できます。

    各トレースは、2 つのデータの競合アクセスが行われた時点でのスレッド呼び出しスタックのペアを参照します。トレースが選択されると、tha ウィンドウの右側ペインの「競合の詳細」タブに、2 つの呼び出しスタックが表示されます (下記参照)。デフォルトで、最初のアクセスの呼び出しスタックの先頭にあるフレームが選択されます。

「デッドロック」タブ

「デッドロック」タブは、1 つ以上のロードされた実験にデッドロックデータが含まれている場合に表示されます。このタブには、アプリケーション内で検出されたデッドロックのリストが表示されます。デフォルトでは、デッドロックのリストの最初のデッドロックが選択されます。

デッドロックごとに、次の情報が表示されます。

  • デッドロックを識別する一意の ID。

  • デッドロックの種類 (潜在的デッドロックまたは実デッドロック)。

  • デッドロックに関係するスレッドの総数。

各スレッドのコンテキストは、「総スレッド数」ラベルの左側のボタンをクリックすることにより表示できます。各スレッドコンテキストには、最初のロック保持と、2 番目のロック取得を試みるデッドロックに対応した 2 つの操作が示されます。

スレッドコンテキストが選択されると、tha ウィンドウの右側ペインの「デッドロックの詳細」タブに、ロック保持とロック要求が行われた 2 つの呼び出しスタックが表示されます (下記参照)。

「デュアルソース」タブ

「デュアルソース」タブは、1 つ以上のロードされた実験にデータ競合またはデッドロックデータのどちらかが含まれている場合に表示されます。「デュアルソース」タブには、選択したデータ競合またはデッドロックに関係した 2 つのソース位置が示されます。

選択したデータ競合の場合、「デュアルソース」タブには、「競合の詳細」タブと同様に選択されたデータ競合の 2 つのアクセスのソース位置が示されます。選択したデッドロックの場合、「デュアルソース」タブには、「デッドロックの詳細」タブと同様に、選択したスレッドによる最初のロック保持と 2 番目のロック取得を試みるデッドロックに対応した 2 つの操作が示されます。

アクセスが行われたソース行は強調表示されます。ソース行が -g を指定してコンパイルされた場合、コンパイラ解説がソースコード内にインタリーブされて表示されることがあります。

各ソース行の左側には、ソース行に関連したメトリックが表示されます。データ競合の場合、表示されるデフォルトのメトリックは排他的競合アクセスメトリックです。このメトリックは、その行でデータの競合アクセスが報告された回数を示します。デッドロックの場合、表示されるデフォルトのメトリックは排他的デッドロックメトリックです。このメトリックは、デッドロックに関与したロック保持またはロック要求処理がそのソース行で報告された回数を示します。

排他的メトリックは、これが出現するソース行にのみ関連します。包括的メトリックは、これが出現するソース行と、そのソース行から呼び出された関数に関連します。カウントメトリックは整数カウントとして示されます。パーセンテージは 0.01% の精度まで表示されます。丸めのため、百分率は合計が正確に 100% にならない場合もあります。

表示されるメトリックは、「データ表示方法を設定」ダイアログボックスを使用して変更できます (下記の「データ表示オプションの選択」を参照)。

ソース表示でのメトリックの列を並べ替えるには、列ヘッダーを表示する位置までドラッグします。

「実験」タブ

「実験」タブは 2 つのパネルに分かれています。上のパネルには、ロードされた実験のロードオブジェクトのノードを含むツリーが表示されます。下のパネルには、tha セッションから出力されたエラーメッセージと警告メッセージが表示されます。

「実験」タブの詳細は、analyzer(1) のマニュアルページを参照してください。

THA ウィンドウ -- 右側のタブ

THA ウィンドウ -- 右側のタブ

tha ウィンドウの右側ペインには、データ競合に関する追加情報を表示するタブが含まれています。「サマリー」タブは常に表示されます。「競合」タブが表示されている場合、「競合の詳細」タブが表示されます。「デッドロック」タブが表示されている場合、「デッドロックの詳細」タブが表示されます。

「サマリー」タブ

「サマリー」タブには、「競合」タブで選択したデータの競合に関するサマリー情報が表示されます。この情報には、オブジェクトファイル名、ソースファイル名、および PC (プログラムカウンタ) アドレスがあります。

「競合の詳細」タブ

「競合の詳細」タブは、「競合」タブが前面に表示されるたび、および「競合」タブから選択が行われるたびに選択されています。ここには、「競合」タブで選択したデータの競合またはトレースに関する詳細情報が表示されます。

「競合の詳細」タブは 2 つのペインに分かれています。上のペインには、選択したデータの競合またはトレースの最初のアクセス (アクセス 1) に関する情報が表示されます。下のペインには、選択したデータの競合またはトレースの 2 番目のアクセス (アクセス 2) に関する情報が表示されます。

「競合」タブからデータの競合またはトレースが選択されると、「競合の詳細」タブには次の情報が表示されます。

  • データの競合またはトレース ID

  • データの競合に関連付けられた仮想アドレス (Vaddr)。データ競合が複数の仮想アドレスで発生した場合、単一のアドレスの代わりに「(複数のアドレス)」と表示されます。

さらに、2 つのアクセスそれぞれに対し、「競合の詳細」タブには次の情報も表示されます。

  • データの競合アクセスが読み取りか書き込みか

  • 「競合」タブのデータの競合が選択されている場合は、「競合の詳細」タブには、データの競合アクセスが行われたときのスレッドのリーフ PC が表示されます。これに対し、「競合」タブのトレースが選択されている場合は、「競合の詳細」タブには、データの競合アクセスが行われたときのスレッドの呼び出しスタックが表示されます。デフォルトでは、呼び出しスタックの先頭にあるフレームが選択されます。

「デッドロックの詳細」タブ

「デッドロックの詳細」タブは、「デッドロック」タブが前面に表示されるたび、または「デッドロック」タブから選択が行われるたびに選択されています。ここには、「デッドロック」タブで選択したスレッドコンテキストの詳細情報が示されます。

選択したスレッドコンテキストごとに、デッドロック ID、デッドロックタイプ、スレッド ID が表示されます。さらに、関連する 2 つのロック処理ごとに、ロック処理の種類 (ロック保持またはロック要求) とスレッドの呼び出しスタックが表示されます。デフォルトで、各呼び出しスタックの先頭にあるフレームが選択されます。

データ競合の検出

データ競合の検出

単一プロセス内の 2 つ以上のスレッドが同じメモリー位置に同時にアクセスし、そのアクセスの少なくとも 1 つが書き込みアクセスであり、スレッドでそのメモリーへのアクセスの制御に排他的ロックを使用していない場合に、データ競合が発生します。このような場合、アクセス順序が定まらないため、その順序によって計算結果が異なる可能性があります。データの競合には、害のないもの (メモリーアクセスをビジーウェイトに使用するときなど) もありますが、データの競合の多くはプログラムのバグによるものです。

データ競合の検出実験は、マルチスレッドプロセスの実行中に検出されたデータの競合を記録します。データ競合の検出は、POSIX スレッド API、Solaris スレッド API、OpenMP、またはこれらの組み合わせを使用して作成されたマルチスレッドアプリケーションで機能します。

データ競合の検出では、次の 3 つの手順を行います。

ステップ 1: コードに計測機構を組み込む

アプリケーションでデータの競合の検出を可能にするには、実行時にメモリーアクセスをモニターするコードをあらかじめ計測しておく必要があります。計測機構の組み込みは、アプリケーションのソースレベルまたはバイナリレベルで行えます。

ソースレベルで計測機構を組み込む場合、アプリケーションのソースコードのコンパイルで、次の特殊なコンパイラオプションが指定されている必要があります。

-xinstrument=datarace

このコンパイラオプションを付けてコンパイラで生成されたコードが、データの競合の検出用に計測されます。

バイナリレベルで計測機構を組み込む場合、discover(1) コマンドで呼び出される検出ツールを使用して、アプリケーションバイナリに計測機構を組み込む必要があります。バイナリが a.out という名前の場合、次のように実行することによって、計測機構を組み込んだバイナリ a.outi を生成できます。

discover -i datarace -o a.outi a.out

検出ツールでは、開かれている共有ライブラリを、それがプログラム内で静的にリンクされているか、dlopen() によって動的に開かれているかにかかわらず、すべて自動的に計測します。discover コマンド行オプション -N を使用して、特定のライブラリを無視したり、discover コマンド行オプション -T を使用して、すべてのライブラリを無視できます。

検出ツールを使用するには、Oracle Solaris 10 update 5 以上または Oracle Solaris 11 搭載のマシンで、Solaris Studio 12 update 1 以降のバージョンのコンパイラを使用して、フラグ -O[n] (n>=0) を付けて入力バイナリをコンパイルする必要があります。それ以前のバージョンの Solaris では、-xbinopt=prepare コンパイラオプションを試してください (SPARC のみ)。

ソースレベルとバイナリレベルのどちらのレベルで計測機構を組み込んだ場合でも、アプリケーションバイナリを構築するときには、-g コンパイラオプションを使用することをお勧めします。そうすれば、データの競合を報告するときに、tha でソースコードと行番号情報を表示できます。

ステップ 2: データ競合の検出実験を作成する

-r race フラグを付けて collect コマンドを使用してアプリケーションを実行し、プロセスの実行中にデータ競合の検出実験を作成します。

収集されるデータ競合の検出のデータには、競合を起こしたデータアクセスのペアが含まれます。データ競合の検出のデータは、「競合アクセス」メトリックに変換されます。

詳細は、collect(1) のマニュアルページを参照してください。

ステップ 3: データ競合の検出実験を検証する

tha または analyzer コマンド (GUI) を使用するか、er_print ユーティリティー (コマンド行) を使用してデータ競合の検出実験を検証できます。

tha コマンドと analyzer コマンドはどちらも GUI インタフェースを表示します。tha コマンドはデフォルトの一連のタブが簡略化されていますが、それ以外は analyzer と同じです。一方、er_print ユーティリティーは、コマンド行インタフェースを表示します。

注: スレッドアナライザは、アプリケーションでのユーザー定義の同期を認識しない場合、誤検出データ競合を報告する場合があります。スレッドアナライザの実行時ライブラリ libtha.so には、ユーザー定義の同期についてスレッドアナライザに知らせ、報告される誤検出数を減らすために使用できる API が用意されています。詳細は、libtha(3) のマニュアルページを参照してください。

デッドロックの検出

デッドロックの検出

デッドロックとは、2 つ以上のスレッドが互いを待機して、永久的にブロック (ハング) されている状況を指します。デッドロックの原因は、プログラムロジックの誤りや、同期機構およびバリアーの不適切な使用など数多くあります。

スレッドアナライザは、相互排他ロックの不適切な使用によって生じたデッドロックを検出します。この種のデッドロックは、マルチスレッドアプリケーションでよく生じます。2 つ以上のスレッドを持つプロセスがあるとします。相互排他ロックの不適切な使用によって生じたデッドロックは、次の 3 つの条件が満たされたときに発生します。

  1. すでにロックを保持しているスレッドが新しいロックを要求し、

  2. それらの要求が同時に行われ、

  3. チェーン内の次のスレッドで保持されているロックを各スレッドが待機するという巡回チェーンを、2 つ以上のスレッドが形成している場合。

デッドロック状況の例を次に示します。

Thread 1:  holds lock A, requests lock B
Thread 2:  holds lock B, requests lock A

プログラムの特定の実行でのデッドロックは、潜在的デッドロックの場合も、実デッドロックの場合もあります。潜在的デッドロックは、プログラムの実行で実際には起きなかったが、スレッドのスケジュールや、スレッドによるロックの要求のタイミングによっては、今後プログラムを実行すると起きる可能性があるデッドロックです。実デッドロックは、プログラムの実行で実際に起きたデッドロックです。実デッドロックでは、関係するスレッドの実行は滞りますが、プロセス全体の実行は滞ることもあれば、そうでないこともあります。

デッドロックの検出実験は、マルチスレッドプロセスの実行中に検出された潜在的デッドロックと実デッドロックの両方を記録します。デッドロックの検出は、POSIX スレッド API、Solaris スレッド API、OpenMP、またはこれらの組み合わせを使用して作成されたマルチスレッドアプリケーションで機能します。

デッドロックの検出では、次の 2 つの手順を行います。

ステップ 1: デッドロックの検出実験を作成する

-r deadlock フラグを付けて collect コマンドを使用してアプリケーションを実行し、プロセスの実行中にデッドロックの検出実験を作成します。

収集されるデッドロックの検出データには、巡回チェーンを構成するロック保持とロック要求が含まれます。デッドロックの検出データは、「デッドロック」メトリックに変換されます。

詳細は、collect(1) のマニュアルページを参照してください。

ステップ 2: デッドロックの検出実験を検証する

tha または analyzer コマンド (GUI) を使用するか、er_print ユーティリティー (コマンド行) を使用してデッドロックの検出実験を検証できます。

tha コマンドと analyzer コマンドはどちらも GUI インタフェースを表示します。tha コマンドはデフォルトの一連のタブが簡略化されていますが、それ以外は analyzer と同じです。一方、er_print ユーティリティーは、コマンド行インタフェースを表示します。

アプリケーションバイナリを構築するときには、-g コンパイラオプションを使用することをお勧めします。そうすれば、デッドロックを報告するときに、tha でソースコードと行番号情報を表示できます。

データ表示方法オプションの選択

データ表示方法オプションの選択

「データ表示方法を設定」ダイアログボックスからデータの表示方法を制御できます。このダイアログボックスは、ツールバーの「データ表示方法の設定」ボタンをクリックするか、「表示」メニューから「データ表示方法の設定」を選択することで、開くことができます。

「データ表示方法の設定」ダイアログボックスには、7 つのタブを持つタブペインが含まれています。詳細は、analyzer(1) のマニュアルページを参照してください。

デフォルト

デフォルト

スレッドアナライザは、現在のディレクトリにある .er.rc ファイル (存在する場合) の指令、ユーザーのホームディレクトリにある .er.rc ファイル (存在する場合) の指令、製品とともにインストールされたシステム er.rc ファイルの指令を処理します。

これらの .er.rc ファイルには、スレッドアナライザを起動したときに表示するタブのデフォルト設定 (rtabs) を含めることができます。「実験」タブ (headers)、「タイムライン」タブ (timeline)、「デュアルソース」タブ (dsrc)、「ソース/逆アセンブリ」タブ (srcdis) を除き、タブには対応するレポートに応じて er_print コマンドによって名前が付けられます。

.er.rc ファイルには、メトリック、ソート、コンパイラの解説オプションの指定、およびソースと逆アセンブリの出力のしきい値の強調表示の各デフォルト設定も含めることができます。ファイルには、ほかのコンパイラのために復号化される C++ 名のパス、「タイムライン」タブと名前の形式のデフォルト設定、および「表示モード」(viewmode) の設定も指定します。

.er.rc ファイルには、初期の実験が読み取られるときに派生実験を選択し読み取るかどうかを制御する設定 en_desc {on|off} も含めることができます。

.er.rc ファイルには、ソースファイルおよびオブジェクトファイルの検索パスを制御する指令を含めることもできます。スレッドアナライザでは、「データ表示方法を設定」ダイアログボックスの「保存」ボタンをクリックして、.er.rc ファイルを保存できます。このダイアログボックスは「表示」メニューから開くことができます。「データ表示方法を設定」ダイアログボックスから .er.rc ファイルを保存した場合、今後呼び出すスレッドアナライザに影響するだけでなく、er_print ユーティリティーと er_src ユーティリティーにも影響します。これらの指令、ファイル、およびその処理の説明については、er_print(1) のマニュアルページを参照してください。

スレッドアナライザは、タブをロードしたときに生成される処理メッセージなどのメッセージを、処理したユーザーの .er.rc ファイルに名前を付けて、そのエラー/警告ログ領域に書き込みます。

関連項目

analyzer (1) , collect (1) , discover (1) , er_archive (1) , er_cp (1) , er_export (1) , er_mv (1) , er_print (1) , er_rm (1) , er_src (1) , tha (1) , libtha (3)

スレッドアナライザのユーザーガイド

パフォーマンスアナライザマニュアル