【问题标题】:Is there anyway to allow one application thread to continue while at a breakpoint in GDB?无论如何,是否允许一个应用程序线程在 GDB 中的断点处继续?
【发布时间】:2011-03-24 01:22:57
【问题描述】:

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

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

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

【问题讨论】:

  • 你的意思是»...,但其他人会被阻止«,对吧?
  • 对。问题不是很清楚吗?编辑:修正错字

标签: c++ c gdb apache-zookeeper


【解决方案1】:

事实证明,使用 Zookeeper,您可以执行一个 hack,以允许会话在 gdb 中中断时继续。这个 hack 利用了 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 中一种未记录的禁用日志记录的方式。

【讨论】:

  • 我应该指出,这种方法并不完美,并且在幕后似乎有些丑陋。有时 Zookeeper 操作会由于未知原因而失败,我怀疑这与会话保持进程窃取会话有关。不管是哪种情况,您都可以通过其他方式解决这个问题,即开发中的客户超时时间长,生产中的超时时间短。
【解决方案2】:

这有帮助:

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

看起来您可以执行类似“thread apply [threadno] break lineno”之类的操作

【讨论】:

  • 好吧,“线程应用”似乎很有帮助,但是您给出的示例会导致特定线程中断。我需要更像'thread apply [blah] dont_break'的东西。
【解决方案3】:

您可以设置线程特定的断点:

(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.

【讨论】:

  • 这只是意味着调试器只有在某些线程到达断点时才会中断——如果发生这种情况,所有线程都将停止。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-12-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多