5.3.5. 個別スレッドのデバッグ
GDB には、個別のスレッドをデバッグし、それらを個別に操作および検査する機能があります。この機能はデフォルトでは有効ではありません。これを実行するには、
set non-stop on
および set target-async on
を使用します。これらは .gdbinit
に追加できます。この機能がオンになると、GDB はスレッドデバッグを実行する準備ができます。
たとえば、以下のプログラムは 2 つのスレッドを作成します。これらの 2 つのスレッドとメインを実行する元のスレッドと合わせると、合計 3 つのスレッドになります。
three-threads.c
これを GDB で検査するためにこのプログラムをコンパイルします。
gcc -g three-threads.c -o three-threads -lpthread gdb ./three-threads
gcc -g three-threads.c -o three-threads -lpthread
gdb ./three-threads
まず、すべてのスレッド関数 thread1、thread2、およびメインにブレークポイントを設定します。
次に、プログラムを実行します。
コマンド
info threads
がプログラムのスレッド要約と現在の状態についての詳細情報の一部を提供することに注意してください。この場合、作成されているのは 1 つのスレッドのみになります。
さらに実行を継続します。
ここで、2 つのスレッドがさらに作成されました。スターマークの付いたスレッドは、現在フォーカスされているスレッドであることを示しています。また、新たに作成されたスレッドの thread2() と thread3() は、初期化関数でそれらに対して設定されたブレークポイントにヒットしました。
実際のスレッドデバッグを開始するには、
thread <thread number>
コマンドを使用してフォーカスを別のスレッドに切り替えます。
Thread 2 は、その関数 thread2() の 20 行目で停止しました。
上記では、thread2 の数行がカウンターの count2 を出力しており、'info threads' の出力に表示されるように thread 2 が 23 行目に置かれています。
次は thread3 です。
Thread 3 は、Sleep ステートメントがあり、実行スピードが遅くなるという点で少し異なっています。これは、無視される IO スレッドの表現として考えてください。このスレッドは無視されるため、その実行は、
continue
を使用して中断せずに続行されます。
continue
の末尾にある & に注意してください。これによって、GDB のプロンプトが戻るため、他のコマンドを実行することができます。interrupt
を使用して thread 3 が再び関連性を持つ場合は、実行が停止される可能性があります。
(gdb) interrupt [Thread 0x7ffff75d2710 (LWP 4688)] #3 stopped. 0x000000343f4a6a6d in nanosleep () at ../sysdeps/unix/syscall-template.S:82 82 T_PSEUDO (SYSCALL_SYMBOL, SYSCALL_NAME, SYSCALL_NARGS)
(gdb) interrupt
[Thread 0x7ffff75d2710 (LWP 4688)] #3 stopped.
0x000000343f4a6a6d in nanosleep () at ../sysdeps/unix/syscall-template.S:82
82 T_PSEUDO (SYSCALL_SYMBOL, SYSCALL_NAME, SYSCALL_NARGS)
また、元のメインスレッドに戻り、これをさらに検査することも可能です。
情報スレッドの出力からも分かるように、他のスレッドはそれらが置かれた場所にあるため、thread 1 のデバッグの影響は受けません。