6

在使用 Apache Zookeeper C 运行时库调试应用程序时,我在使用 GDB 中的默认全停止模式设置断点时遇到了问题。由于 Zookeeper 线程无法运行,服务器将使会话超时,从而删除您可能创建的任何临时 znode。使用不间断模式我可以防止这种情况发生,但是我失去了能够检查任何非 Zookeeper 线程状态的便利。

GDB 中有没有办法指定一个(或多个)线程在断点被击中时将继续在应用程序中运行,但其他线程将停止运行?这样我就可以检查我关心的线程的状态,而忽略那些我想在后台运行的线程的状态。

编辑:这本质上是不停止 gdb 中的所有线程的副本。使用不间断模式的后台命令的解决方案基本上解决了我的问题,因为我可以随时停止线程并异步重新启动它们,所以也许我们应该关闭这个。

4

3 回答 3

1

事实证明,使用 Zookeeper,您可以执行一个 hack,以允许会话在 gdb 中中断时继续。这个黑客利用了 Zookeeper 和 gdb 的一些属性:

  • 您可以拥有多个具有相同会话 ID 的 Zookeeper 客户端
  • gdb 不会在父断点处停止子进程
  • 您可以忽略子进程中的 gdb 信号而不影响父进程

基于此,解决方案变成了生成一个子进程,该子进程使用与父进程相同的客户端 ID 连接到 Zookeeper,并且不执行任何其他操作。然而,Zookeeper 客户端具有会话移动的概念,客户端每隔一段时间就会切换它们所连接的服务器。如果您有两个具有相同会话 ID 的客户端,其中一个可能会移动,而另一个连接到不保留其会话的服务器。为了防止这种情况,孩子必须只连接到父母当前连接的服务器。因此,父母和孩子如下所示:

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 对此进行了测试,它的工作原理与描述的一样。当您执行此 hack 时,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 回答