6

Apache Zookeeper Cランタイムライブラリを使用してアプリケーションをデバッグしているときに、GDBのデフォルトのオールストップモードでブレークポイントを設定すると問題が発生します。Zookeeperスレッドを実行できない場合、サーバーはセッションをタイムアウトし、作成した一時的なznodeを削除します。ノンストップモードを使用すると、これを防ぐことができますが、Zookeeper以外のスレッドの状態を調べることができるという便利さが失われます。

GDBに、ブレークポイントに達したときに1つ(または複数)のスレッドがアプリケーションで実行を継続するが、他のスレッドは実行を停止するように指定する方法はありますか?そうすれば、気になるスレッドの状態を調べて、バックグラウンドで実行したいスレッドの状態を無視することができます。

編集:これは基本的に、gdb内のすべてのスレッドを停止しないことの複製です。ノンストップモードでバックグラウンドコマンドを使用するための解決策は、スレッドを停止し、必要なときに非同期で再起動できるため、基本的に問題を解決します。したがって、これを閉じる必要があります。

4

3 に答える 3

1

Zookeeper を使用すると、gdb で中断されている間もセッションを続行できるようにするために実行できるハックがあることがわかりました。このハックは、Zookeeper と gdb のいくつかのプロパティを利用しています。

  • 同じセッション ID を持つ複数の Zookeeper クライアントを持つことができます
  • gdb は親ブレークポイントで子プロセスを停止しません
  • 親プロセスに影響を与えることなく、子プロセスの gdb シグナルを無視できます

これに基づいて、ソリューションは、親と同じクライアント ID で Zookeeper に接続し、他に何もしない子プロセスを生成します。ただし、Zookeeper クライアントにはセッション移動の概念があり、クライアントは接続先のサーバーを頻繁に切り替えます。同じセッション ID を持つ 2 つのクライアントがある場合、一方が移動して、もう一方がセッションを保持していないサーバーに接続されたままになる可能性があります。これを防ぐには、子は親が現在接続しているサーバーにのみ接続する必要があります。したがって、親と子は次のようになります。

Parent(zh):
  host = zookeeper_get_connected_host(zh)
  client_id = zoo_client_id(zh)
  if fork == 0
    exec child host client_id
  end

Child(host, client_id):
  ignore SIGINT
  zh = zookeeper_init(host, client_id)
  while(true)
    sleep
  end

libzookeeper_mt-0.3.3 を使用してこれをテストしたところ、説明どおりに動作します。このハックを行うと、Zookeeper のログから厄介な問題が発生し始め、イライラする可能性があります。ログを無視できない場合は、次のようにオフにすることができます。

zoo_set_debug_level((ZooLogLevel)0);

これは、ログ記録を無効にする Zookeeper の文書化されていない方法です。

于 2011-03-23T17:22:57.493 に答える
-1

これは次のことに役立ちます。

http://www.delorie.com/gnu/docs/gdb/gdb_25.html

「thread apply [threadno] break lineno」のようなことができるようです

于 2011-03-09T19:20:39.363 に答える
-1

スレッド固有のブレークポイントを設定できます。

(gdb) help break
Set breakpoint at specified line or function.
break [LOCATION] [thread THREADNUM] [if CONDITION]
LOCATION may be a line number, function name, or "*" and an address.
If a line number is specified, break at start of code for that line.
If a function is specified, break at start of code for that function.
If an address is specified, break at that exact address.
With no LOCATION, uses current execution address of the selected
stack frame.  This is useful for breaking on return to a stack frame.

THREADNUM is the number from "info threads".
CONDITION is a boolean expression.
于 2011-03-10T23:08:28.970 に答える