是否有办法允许一个应用程序线程在 GDB 中的断点处继续运行?

发布于 2024-10-20 23:43:09 字数 457 浏览 1 评论 0原文

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

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

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

While debugging an application using the Apache Zookeeper C runtime library, I run into issues when setting breakpoints with the default all-stop mode in GDB. With the Zookeeper thread being unable to run, the server will timeout the session and thus delete any ephemeral znodes you may have created. Using non-stop mode I can prevent this from occurring, but I lose the convenience of being able to examine the state of any non-Zookeeper thread.

Is there a way in GDB to specify that one (or more) threads will continue running in an application when a breakpoint is hit, but the others will stop running? That way I can examine the state of threads I care about and ignore the state of those I want running in the background.

Edit: This is essentially a duplicate of not stopping all threads in gdb. The solution there to use background commands with non-stop mode essentially solves my problem since I can stop threads and restart them asynchronously whenever I want to, so maybe we should close this one.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

滥情哥ㄟ 2024-10-27 23:43:09

事实证明,使用 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 对此进行了测试,它的工作原理如下。当您进行此黑客攻击时,Zookeeper 日志中会开始出现一些令人沮丧的内容。如果您无法忽略日志,则可以按如下方式关闭它们:

zoo_set_debug_level((ZooLogLevel)0);

这是 Zookeeper 中禁用日志记录的一种未记录的方法。

With Zookeeper it turns out there is a hack you can perform in order to allow a session to continue while interrupted in gdb. This hack leverages a few properties of Zookeeper and gdb:

  • You can have multiple Zookeeper clients with same session ID
  • gdb doesn't stop child processes at parent breakpoints
  • You can ignore gdb signals in a child process without affecting the parent

Based on this, the solution becomes spawning a child process which connects to Zookeeper with the same client id as the parent and does nothing else. Zookeeper clients however have the notion of session moving, where every so often the client will switch which server they are connected to. If you have two clients with same session ID, one of them could move leaving the other connected to a server that doesn't hold their session. To prevent this, the child must only connect to the server the parent is currently connected to. The parent and child thus look like the following:

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

I tested this using libzookeeper_mt-0.3.3 and it works as described. Some nastiness starts spewing out of the Zookeeper logs when you do this hack which can be frustrating. If you can't ignore the logs, you can turn them off as follows:

zoo_set_debug_level((ZooLogLevel)0);

It's an undocumented way in Zookeeper of disabling logging.

忘你却要生生世世 2024-10-27 23:43:09

这有帮助:

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

看起来你可以做类似“thread apply [threadno] break lineno”的事情

This helps:

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

Looks like you can do something like "thread apply [threadno] break lineno"

攒一口袋星星 2024-10-27 23:43:09

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

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

You can set thread-specific breakpoints:

(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.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文