前: Signals, 上: Stopping


5.4 マルチスレッド・プログラムの停止と起動

ユーザ・プログラムが複数のスレッド (see Debugging programs with multiple threads) を持つ場合、 すべてのスレッドにブレイクポイントを設定するか、 特定のスレッドにブレイクポイントを設定するかを選択することができます。

break linespec thread threadno
break linespec thread threadno if ...
linespecはソース行を指定します。 記述方法はいくつかありますが、 どの方法を使っても結果的にはソース行を指定することになります。

breakコマンドに修飾子`thread threadno'を使用することで、 ある特定のスレッドがこのブレイクポイントに到達したときだけGDBがプログラムを停止するよう、 指定することができます。 ここでthreadnoは、 GDBによって割り当てられるスレッド識別番号で、 `info threads'コマンドによる出力の最初の欄に表示されるものです。

ブレイクポイントを設定する際に`thread threadno'を指定しなければ、 そのブレイクポイントはユーザ・プログラム内部のすべてのスレッドに適用されます。

条件付きのブレイクポイントに対してもthread識別子を使用することができます。 この場合、 以下のように`thread threadno'をブレイクポイント成立条件の前に記述してください。

          (gdb) break frik.c:13 thread 28 if bartab > lim
     

いかなる理由によるのであれGDB配下においてユーザ・プログラムが停止した場合、 カレント・スレッドだけではなく、 すべての実行スレッドが停止します。 これにより、 知らないうちに状態の変化が発生することを心配することなく、 スレッドの切り替えも含めて、 プログラム全体の状態を検査することができます。

逆に、 プログラムの実行を再開したときには、 すべてのスレッドが実行を開始します。 これは、 stepコマンドやnextコマンドによるシングル・ステップ実行の場合でも同様です。

特にGDBは、 すべてのスレッドの歩調を合わせてシングル・ステップ実行することはできません。 スレッドのスケジューリングは、 デバッグ対象のマシンのオペレーティング・システムに依存する (GDBが管理するわけではない) ので、 カレント・スレッドがシングル・ステップの実行を完了する前に、 他のスレッドは複数の文を実行してしまうかもしれません。 また、 プログラムが停止するとき、 他のスレッドは2つの文の間の境界のところでぴったり停止するよりも、 文の途中で停止してしまう方が一般的です。

また、 継続実行やステップ実行の結果、 プログラムが別のスレッド内で停止してしまうこともありえます。 最初のスレッドがユーザの要求した処理を完了する前に、 他のスレッドがブレイクポイントに到達した場合、 シグナルを受信した場合、 例外が発生した場合には、 常にこのようなことが発生します。

OSによっては、 OSスケジューラをロックすることによって、 ただ1つのスレッドだけが実行されるようにすることができます。

set scheduler-locking mode
スケジューラのロッキング・モード(locking mode)を設定します。 offの場合は、 ロックのメカニズムは機能せず、 任意の時点において、 どのスレッドも実行される可能性を持ちます。 onの場合は、 再始動(resume)されるスレッドの優先順位が低い場合には、 カレント・スレッドだけが実行を継続することができます。 stepモードでは、 シングル・ステップ実行のための最適化が行われます。 ステップ実行をしている間、 他のスレッドが「プロンプトを横取りする」ことがないよう、 カレント・スレッドに占有権が与えられます。 また、 ステップ実行をしている間、 他のスレッドはきわめて稀にしか (あるいは、 まったく) 実行するチャンスを与えられません。 nextコマンドによって関数呼び出しの次の行まで処理を進めると、 他のスレッドが実行される可能性は高くなります。 また、 continueuntilfinishのようなコマンドを使用すると、 他のスレッドは 完全に自由に実行されることができます。 しかし、 そのタイムスライスの中でブレイクポイントに到達しない限り、 他のスレッドが、 デバッグの対象となっているスレッドから、 GDBプロンプトを横取りすることはありません。
show scheduler-locking
スケジューラの現在のロッキング・モードを表示します。