dbx には、マルチスレッドプログラムをデバッグする通常の機能に加え、OpenMP プログラムのデバッグを行う機能もあります。
dbx は、並列領域にシングルステップ実行できます。並列領域は OpenMP の実行時ライブラリから始まり呼び出されるため、実際には一回のシングルステップの中で、この目的で作成されたスレッドが実行時ライブラリを幾重にも呼び出しを行うことになります。並列領域にシングルステップ実行すると、最初にブレークポイントに到達したスレッドによってプログラムが停止します。このスレッドは、ステップを開始したマスターステップではなく、スレーブスレッドになります。
たとえば、Fortran コードを 「コンパイラによる OpenMP コードの変換」で参照し、マスタースレッド t@1 が行 10 にあると想定します。行 12 に対してシングルステップを実行すると、スレーブスレッド t@2、t@3、および t@4 が生成され、実行時ライブラリ呼び出しを実行します。スレッド t@3 が最初にブレークポイントに到達し、プログラムの実行が停止します。このように、スレッド t@1 によって開始されたシングルステップ実行は、次のスレッドで終了します。t@3 この動作は、シングルステップ実行後も通常は以前と同じスレッドにいる普通のステップ実行とは異なります。
dbx は、shared、private、および thread-private 変数をすべて出力します。並列領域外で thread private 変数を出力しようとすると、マスタースレッドのコピーが出力されます。whatis コマンドは、並列構文内の shared 変数と private 変数のデータ共有属性を出力します。thread-private 変数については、これらの変数が並列構文内にあるかないかにかかわらず、データ共有属性を出力します。次に例を示します。
(dbx) whatis p_a # OpenMP first and last private variable int p_a; |
print -s expression コマンドは、式に private または thread private 変数が含まれている場合に、現在の OpenMP の並列領域の各スレッドの式 expression の値を出力します。次に例を示します。
(dbx) print -s p_a thread t@3: p_a = 3 thread t@4: p_a = 3 |
式に private 変数または thread private 変数が含まれない場合は、1 つの値だけが出力されます。
dbx は、現在の並列領域、または指定された並列領域に関する説明を出力できます。これには、親領域、並列領域 ID、チームのサイズ (スレッド数)、プログラムの場所 (プログラムのカウンタアドレス) が含まれます。次に例を示します。
(dbx) omp_pr parallel region 127283434369843201 team size = 4 source location = test.c:103 parent = 127283430568755201 |
また、現在の並列領域または指定された並列領域から、そのルートに至るまで、パス上のすべての並列領域の説明も出力できます。次に例を示します。
(dbx) omp_pr -ancestors parallel region 127283434369843201 team size = 4 source location = test.c:103 parent = 127283430568755201 parallel region 127283430568755201 team size = 4 source location = test.c:95 parent = <no parent> |
さらに、並列領域ツリー全体も出力できます。次に例を示します。
(dbx) omp_pr -tree parallel region 127283430568755201 team size = 4 source location = test.c:95 parent = <no parent> parallel region 127283434369843201 team size = 4 source location = test.c:103 parent = 127283430568755201 |
詳細については、「omp_pr コマンド」を参照してください。
dbx は、現在のタスク領域、または指定されたタスク領域に関する説明を出力できます。これには、タスク領域 ID、状態 (生成済み、実行中、または待機中)、実行中のスレッド、プログラムの場所 (プログラムのカウンタアドレス)、未完了の子、親が含まれます。次に例を示します。
(dbx) omp_tr task region 65540 type = implicit state = executing executing thread = t@4 source location == test.c:46 unfinished children = 0 parent = <no parent> |
また、現在のタスク領域または指定されたタスク領域から、そのルートに至るまで、パス上のすべてのタスク領域の説明も出力できます。
(dbx) omp_tr -ancestors task region 196611 type = implicit state = executing executing thread = t@3 source location - test.c:103 unfinished children = 0 parent = 131075 task region 131075 type = implicit state = executing executing thread = t@3 unfinished children = 0 parent = <no parent> |
さらに、タスク領域ツリー全体も出力できます。次に例を示します。
(dbx) omp_tr -tree task region 10 type = implicit state = executing executing thread = t@10 source location = test.c:103 unfinished children = 0 parent = <no parent> task region 7 type = implicit state = executing executing thread = t@7 source location = test.c:103 unfinished children = 0 parent = <no parent> task region 6 type implicit state = executing executing thread = t@6 source location = test.c:103 unfinished children = 0 parent = <o parent> task region 196609 type = implicit state = executing executing thread = t@1 source location = test.c:95 unfinished children = 0 parent = <no parent> task region 262145 type = implicit state = executing executing thread = t@1 source location = test.c:103 unfinished children - 0 parent = 196609 |
詳細については、「omp_tr コマンド」を参照してください。
dbx は、現在のループに関する説明を出力できます。これには、スケジューリングの型 (静的、動的、ガイド付き、自動、または実行時)、番号付きまたは番号なし、範囲、ステップ数または刻み幅、および繰り返し回数が含まれます。次に例を示します。
(dbx) omp_loop ordered loop: no lower bound: 0 upper bound: 3 step: 1 chunk: 1 schedule type: static source location: test.c:49 |
詳細については、「omp_loop コマンド」を参照してください。
dbx は、現在のチーム、または指定された並列領域のチームのすべてのスレッドを出力できます。次に例を示します。
(dbx) omp_team team members: 0: t@1 state = in implicit barrier, task region = 262145 1: t@6 state = in implicit barrier, task region = 6 2: t@7 state = working, task region = 7 3: t@10 state = in implicit barrier, task region = 10 |
詳細については、「omp_team コマンド」を参照してください。
OpenMP コードをデバッグするとき、thread -info は、現在のスレッドまたは指定のスレッドに関する通常の情報に加え、OpenMP スレッド ID、並列領域 ID、タスク領域 ID、および OpenMP スレッドの状態も出力します。詳細については、「thread コマンド」を参照してください。
dbx 現在のスレッド、または現在のチームのすべてのスレッドで、次に検出された並列領域の実行を直列化します。詳細については、「omp_serialize コマンド」を参照してください。
並列領域で実行が停止されると、アウトラインサブルーチンを含んだスタックトレースがwhere コマンドによって表示されます。
(dbx) where current thread: t@4 =>[1] _$d1E48.main(), line 52 in "test.c" [2] _$p1I46.main(), line 48 in "test.c" --- frames from parent thread --- current thread: t@1 [7] main(argc = 1, argv = 0xffffffff7fffec98), line 46 in "test.c" |
スタックの上位フレームはアウトライン関数のフレームです。コードが略述されているにもかかわらず、ソース行番号は依然として 15 にマップされます。
並列領域で実行が停止されたときに、関連フレームがアクティブ状態である場合、スレーブスレッドの where コマンドはマスタースレッドのスタックトレースを出力します。マスタースレッドの where コマンドは完全トレースバックを行います。
まず omp_team コマンドを実行して現在のチームのすべてのスレッドをリストし、次にマスタースレッド (OpenMP スレッド ID が 0 のスレッド) に切り替え、そのスレッドからスタックトレースを取得することによって、実行が、スレーブスレッドでブレークポイントにどのように到達したかを判断することもできます。
並列領域で実行が停止すると、dump コマンドによって private 変数の複数のコピーが出力されます。次の例では、dump c コマンドが変数 i の 2 つのコピーを出力します。
[t@1 l@1]: dump i = 1 sum = 0.0 a = ARRAY i = 1000001 |
変数 i の 2 つのコピーが出力されるのは、アウトラインルーチンがホストルーチンのネストされた関数として実装され、private 変数がアウトラインルーチンの局所変数として実装されます。dump コマンドがスコープ内のすべての変数を出力するため、ホストルーチン内の i およびアウトラインルーチン内の i の両方が表示されます。
dbx は、OpenMP コードで stop、when、および trace コマンドとともに使用できるイベントを提供します。これらのコマンドとともにイベントを使用する方法については、「イベント指定の設定」を参照してください。
バリアーに入るスレッドのイベントを追跡します。
type は次のいずれかです。
明示的なバリアーを追跡する explicit
暗黙的なバリアーを追跡する implicit
type を指定しなければ、明示的なバリアーだけが追跡されます。
state は次のいずれかです。
いずれかのスレッドがバリアーに入ったときにイベントをレポートする enter
いずれかのスレッドがバリアーを出たときにイベントをレポートする exit
すべてのスレッドがバリアーに入ったときにイベントをレポートする all_entered
state を指定しない場合のデフォルトは all_entered です。
enter または exit を指定するときにスレッド ID を含めると、そのスレッドのみ追跡を行えます。
taskwait に入るスレッドのイベントを追跡します。
state は次のいずれかです。
スレッドが taskwait に入ったときにイベントをレポートする enter
すべての子タスクが完了したときにイベントをレポートする exit
state を指定しない場合のデフォルトは exit です。
番号付き領域に入るスレッドのイベントを追跡します。
state は次のいずれかです。
番号付き領域が開始したときにイベントをレポートする begin
スレッドが番号付き領域に入ったときにイベントをレポートする enter
スレッドが番号付き領域を出たときにイベントをレポートする exit
state を指定しない場合のデフォルトは enter です。
クリティカルリージョンに入るスレッドのイベントを追跡します。
微細領域に入るスレッドのイベントを追跡します。
state は次のいずれかです。
微細領域が開始したときにイベントをレポートする begin
スレッドが微細領域を出たときにイベントをレポートする exit
state を指定しない場合のデフォルトは begin です。
フラッシュを実行するスレッドのイベントを追跡します。