GDBデバッグマルチプロセス/スレッド


GDBデバッグマルチプロセスとマルチスレッド
Linuxで作業し、VIMエディタを使用し、デバッグしてGDBを使用します.金科玉律のようだが、熟練して使うには力がかかる.VIMエディタ、各種のショートカットキーを熟練しなければならなくて、さもなくば、初心者に対して、まるで悪夢です!GDBデバッガは、GUIインタフェースに比べて直感的ではありませんが、機能は強力です!本稿ではnghttp 2のマルチプロセス/スレッドデバッグを例に挙げます.本題に入る!
1マルチプロセス[process]とマルチスレッド[thread]
私たちが書いたのはマルチスレッドプログラムで、1つのプロセスの下で複数のスレッドを開きました.マルチプロセスのプログラムはめったに関連しません.(スレッドとプロセスの違いは言うまでもない!).マルチプロセスのプログラムは一般的にサーバープログラムであり、例えばnginx、nghttp 2などであり、起動時に1つのmasterプロセスと1つ以上のworkerプロセスが作成され、masterプロセスのタスクはworkerプロセスを管理し、workerプロセスは主に業務を処理する.各workerプロセスでは、1つ以上のスレッドが実行される場合があります.
2プロセス番号PID
プログラムを起動する時、普通は対応するプロセス番号PIDがあって、サーバープログラムはmasterプロセスとworkerプロセスがあって、workerプロセスが業務を処理しているので、私達はworkerプロセスのPIDが必要です
ps -ef | grep <program>

一般的にmasterプロセスは上、workerプロセスは下、workerプロセス番号も一般的にmasterプロセス番号より大きく、作成順序に関係します.
プロセス番号を取得し、GDBを起動してデバッグできます.
3マルチプロセスデバッグ方法
3.1 attach PID
attachはデバッグプロセスの最も一般的な方法であり、実行可能プログラムと対応するPIDがあればよい.プログラムの実行が速すぎてattachに間に合わなかったらどうしますか?プロセス起動後にsleepを10 sなどの時間設定してattachするなど、メインプログラムへの遅延アクセス方法を採用することができる.方法1はsleepを必要とし、方法2は必要とせず、gdbでプログラムの実行を直接制御し、直接デバッグすることができる.
attach <PID>

3.2 set follow-fork-mode child
GDB set follow-fork-mode child gdbを設定すると、ブレークポイントで停止するまでforkの後にサブプロセスが直接実行されます.
nghttpxインスタンスで
2つの方法を提供します.1つは、gdbを使用してパラメータを持って実行するマルチプロセスプログラムを先に実行することです.方法1:
  • 起動、マルチプロセスプログラム.nghttpx –conf=conf/nghttpx.conf
  • workerプロセスPID,ps-ef|grep nghttpx
  • を表示
  • gdb
  • を起動
  • attach PID(workerプロセス)
  • ブレークポイントの設定など、
  • 要求を送信し、デバッグ
  • を開始する.
    方法2:
  • gdb bin/nghttpx
  • 設定パラメータset args–conf=conf/nghttpx.conf
  • set follow-fork-mode childを設定し、gdbはfork後にサブプロセス//設定を直接実行し、
  • をデバッグできません.
  • ブレークポイントの設定など
  • run
  • 要求を送信し、デバッグ
  • を開始する.
    4マルチスレッドデバッグ
    4.1 GDBマルチスレッドデバッグの基本コマンド
    info threadsは現在デバッグ可能なすべてのスレッドを表示し、各スレッドにはGDBが割り当てられたIDがあり、後でスレッドを操作するときにこのIDが使用されます.前に*があるのは、現在デバッグされているスレッドです.thread IDは、現在デバッグされているスレッドが指定されたIDのスレッドであることを切り替えます.
    break thread_test.c:123 thread allすべてのスレッドの対応する行にブレークポイントを設定
    thread apply ID 1 ID 2 commandは、1つまたは複数のスレッドに対してGDBコマンドcommandを実行させる.
    thread apply all commandは、デバッグされたすべてのスレッドに対してGDBコマンドcommandを実行させる.
    set scheduler-locking off|on|step現在デバッグされているスレッドをstepまたはcontinueコマンドでデバッグする場合、他のスレッドも同時に実行されますが、どのようにしてデバッグされたプログラムだけを実行させますか?このコマンドでこのニーズを実現できます.offはスレッドをロックしません.つまり、すべてのスレッドが実行されます.これがデフォルトです.on現在のデバッガのみが実行されます.Stepは単一ステップでnextが関数を通過した場合(状況に詳しい人は知っているかもしれませんが、これは実はブレークポイントを設定してcontinueの動作であることを知っています)以外は、現在のスレッドだけが実行されます.
    4.2例
    info threads
      4 Thread 1099119552 (LWP 12940)   0xffffe002 in ?? ()
      3 Thread 1090731072 (LWP 12939)   0xffffe002 in ?? ()
      2 Thread 1082342592 (LWP 12938)   0xffffe002 in ?? ()
    * 1 Thread 1073951360 (LWP 12931)   main (argc=1, argv=0xbfffda04) at thread.c:21

    thread THREADNUMBERで切り替え、THREADNUMBERは前述のスレッド番号1,2,3,4である.次の例では、アクティブなスレッドを1から4に切り替えます.
    (gdb) info threads
       4 Thread 1099119552 (LWP 12940)   0xffffe002 in ?? ()
       3 Thread 1090731072 (LWP 12939)   0xffffe002 in ?? ()
       2 Thread 1082342592 (LWP 12938)   0xffffe002 in ?? ()
    * 1 Thread 1073951360 (LWP 12931)   main (argc=1, argv=0xbfffda04) at thread.c:21
    (gdb) thread 4
    [Switching to thread 4 (Thread 1099119552 (LWP 12940))]#0   0xffffe002 in ?? ()
    (gdb) info threads
    * 4 Thread 1099119552 (LWP 12940)   0xffffe002 in ?? ()
       3 Thread 1090731072 (LWP 12939)   0xffffe002 in ?? ()
       2 Thread 1082342592 (LWP 12938)   0xffffe002 in ?? ()
       1 Thread 1073951360 (LWP 12931)   main (argc=1, argv=0xbfffda04) at thread.c:21

    あとは直接スレッド関数にブレークポイントを設定し、continueをそのブレークポイントに設定します.一般的にマルチスレッドの場合、同時に実行されるので、set scheduler-locking onを設定すると、現在のスレッドのみをデバッグします.