dbx コマンドによるデバッグ

マルチスレッドプログラムでの dbx の使用

マルチスレッド機能は、dbx の標準な機能です。

dbx の提供する主なマルチスレッド機能は次のとおりです。

スコープを特定のスレッドに制限できます。dbx は、カーソルを現在のスレッドまたは活動中のスレッドに維持します。これは、thread コマンドによって操作できます。カレントスレッドをデフォルトスレッドとして使用するのは、where コマンドと thread -info コマンドだけです。

スレッド番号

dbx は、thr_create() によって返される各スレッド (型 thread_t) の ID を認識します。この構文は t@number です。

LWP 番号

dbx は、/proc (マニュアルページ procfs(4)) インタフェースによって表示される各 LWP (型 lwpid_t) の ID を認識します。この構文は l@number です。

特定スレッドのブレークポイント

通常のブレークポイントをフィルタ処理することによって、特定スレッドにブレークポイントを設定できます。


stop in foo -thread t@4

ここで、t@4 は ID 4 のスレッドを示します。

あるスレッドがブレークポイントに達すると、すべてのスレッドが停止します。これは、「同時停止」または「世界の停止」と呼ばれています。

/proc と LWP の立場から見ると、これは同期デバッグです。

スレッドのナビゲートを容易にするには、次のコードを .dbxrc に追加してください。


_cb_prompt() {
        if [ $mtfeatures = “true”]
        then
                PS1='[$thread $lwp]: '
        else
                PS1=”(dbx-$proc) “
        fi
}

dbx によるマルチスレッドアプリケーションの識別

アプリケーションが -lthread によってリンクされている場合、dbx はそれをマルチスレッドと想定します。

コレクタ、RTC、fix と continue、およびウォッチポイント

コレクタおよび fixcontinue は、マルチスレッドアプリケーションで動作します。RTC はマルチスレッドアプリケーションで動作しますが、libthread パッチが必要です。

ウォッチポイントの実装は、オペレーティングシステムと関係ありません。また、マルチスレッドアプリケーションでデッドロックなどの問題がすぐに起こるおそれがあります。

マルチスレッドの注意点

特定のスレッドを再開するときに、ほかのスレッドが静止していて、再開されるそのスレッドが必要とする可能性のある資源を保持している場合、プログラムはすぐにデッドロック状態になります。

libthread データ構造はユーザースペースにあって、はぐれポインタが原因のバグによって破壊されるおそれがあります。このような場合には、スレッドの同等機能に似た lwpslwp のようなコマンドを使用して LWP レベルで作業することをお勧めします。

スリープ中のスレッド

スリープ中のスレッドの実行を「強いる」ことはできません。通常、マルチスレッドアプリケーションをデバッグする場合は、プログラムの自然な実行フローを変更するのではなく、「後へ下がって監視」することをお勧めします。

thr_join、thr_create()、および thr_exit

スレッドリストから、どのスレッド ID がどの起動関数によるものかを判別することができます。この「ベース関数」は、スレッドリストに出力されます。

既存のマルチスレッドプロセスに接続する場合、どのスレッドが活動中になるかを判断することはできません。

活動中のスレッドが thr_create を実行する場合、カレントスレッドは「作成スレッド」にとどまります。follow_fork に従って考えると、これは親になります。

サンのマルチスレッドモデルには、真のスレッド用のフォークセマンティクスがありません。スレッドツリーや、プロセスの場合のような親子関係がありません。thr_join() は、単純化された表面上のものにすぎません。

活動中のスレッドが thr_exit を実行すると、dbx はダミーの「停止」スレッドを活動中にします。このスレッドは、t@x と表されます。