マルチスレッドのプログラミング

マルチスレッドプログラムのデバッグ

よく起こるミス

以下に、マルチスレッドプログラミングでよく起こるミスを示します。

次の点にも注意してください。マルチスレッドプログラムの動きは、特にバグがある場合には、同じ入力で続けて実行しても再現性がないことがよくあります。これは、スレッドのスケジューリングの順序が定まっていないからです。

一般にマルチスレッドプログラムのバグは、決定的というよりも統計的な発生傾向を示します。このため実行レベルの問題を見つけるには、ブレークポイントによるデバッグよりもトレースの方が有効です。

TNF ユーティリティによる追跡とデバッグ

TNF ユーティリティ (Solaris システムの一部) は、アプリケーションとライブラリからの性能解析情報の収集、追跡、デバッグに使用します。TNF ユーティリティは、カーネルおよび複数のユーザプロセスとスレッドからの追跡情報を集約するので、マルチスレッドコードに特に有用です。

TNF ユーティリティを使用すると、マルチスレッドプログラムの追跡とデバッグが容易になります。

truss(1) の使用

システムコールとシグナルの追跡については、truss(1) を参照してください。

adb(1) の使用

マルチスレッドプログラム内ですべてのスレッドを結合するときは、スレッドと LWP とは同義になります。その場合は、マルチスレッドプログラミングをサポートする以下の adb コマンドを用いて、各スレッドにアクセスできます。

表 7-3 マルチスレッド対応の adb コマンド

pid:A

pid で指定したプロセスに接続する。プロセスと、そのすべての LWP は停止する。

:R

プロセスから切り離す。プロセスと、そのすべての LWP は再開される。 

$L

(停止した) プロセス内の有効な LWP を一覧表示する。 

n:l

フォーカスを n で指定した LWP に切り替える。

$l

現在のフォーカスの LWP を表示する。 

num:i

num で指定したシグナルを無視する。

以下のコマンドは、条件付きブレークポイントを設定するためによく使用されます。

表 7-4 adb ブレークポイントの設定

[label],[count]:b [expression]

expression の評価結果が 0 のときにブレークポイントにヒットする。

foo,ffff:b <g7-0xabcdef

g7 = 0xABCDEF (16 進数値) のときに foo で停止する。

dbx の使用

dbx ユーティリティでは、C++、ANSI C、FORTRAN のソースプログラムをデバッグしたり、実行したりできます。dbx のコマンドは、 デバッガと同じコマンドを受けつけますが、標準端末 (tty) インタフェースを使用する点が異なります。dbx とデバッガのどちらも、現在はマルチスレッドプログラムのデバッグをサポートしています。dbx とデバッガの詳細は、dbx(1) のマニュアルページおよび『Sun WorkShop 入門』 を参照してください。

以下に示す表 7-5 にある dbx のオプションは、すべてマルチスレッドアプリケーションをサポートできます。

表 7-5 dbx のマルチスレッドプログラム用オプション

オプション 

意味 

cont at line [sig signo id]

line で指定した行から signo で指定したシグナルで実行を再開する。id は実行を再開するスレッドまたは LWP を指定する (デフォルトの値は all)。

lwp

現在の LWP を表示する。指定の LWP (lwpid) に切り替える。

lwps

現在のプロセスの、すべての LWP を一覧表示する。 

next ... tid

指定のスレッドをステップ実行する。関数呼び出しをスキップするときは、その関数呼び出しの間だけ、すべての LWP の実行が暗黙のうちに再開される。実行可能でないスレッドをステップ実行できない。 

next ... lid

指定の LWP をステップ実行する。その LWP のスレッドが実行可能であることが必要。関数をスキップするとき、すべての LWP の実行が暗黙のうちに再開されることはない。  

step... tid

指定のスレッドをステップ実行する。関数呼び出しをスキップするときは、その関数呼び出しの間だけ、すべての LWP の実行が暗黙のうちに再開される。実行可能でないスレッドをステップ実行できない。 

step... lid

指定の LWP をステップ実行する。関数をスキップするとき、すべての LWP の実行が暗黙のうちに再開されることはない。  

stepi... lid

指定の LWP 

stepi... tid

指定のスレッドが実行可能である LWP 

thread

現在のスレッドを表示する。指定のスレッド (tid) に切り替える。以下の tid のデフォルト値は現在のスレッド

thread -info [ tid ]

指定のスレッドの全情報を表示する。 

thread -locks [ tid ]

指定のスレッドが保持しているロックを一覧表示する。 

thread -suspend [ tid ]

指定のスレッドを停止状態にする。  

thread -continue [ tid ]

指定のスレッドの停止状態を解除する。 

thread -hide [ tid ]

指定のスレッド (または現在のスレッド) を見えなくする。このスレッドは、threads オプションのリストには表示されない。

thread -unhide [ tid ]

指定のスレッド (または現在のスレッド) の隠蔽を解除する。 

allthread-unhide

全スレッドの隠蔽を解除する。  

threads

全スレッドを一覧表示する。  

threads-all

通常は表示されないスレッド (ゾンビ) を表示する。  

all|filterthreads-mode

threads オプションのスレッド一覧表示にフィルタをかけるかどうかを指定する。

auto|manualthreads-mode

スレッドリストの自動更新機能を有効にする。  

threads-mode

現在のモードをエコーする。以前の任意の書式に続けてスレッドまたは LWP の ID を指定すれば、指定のエンティティのトレースバックを得ることができる。