Is there a way to allow a single application thread to continue running at a breakpoint in GDB?

When debugging an application using the Apache Zookeeper C runtime library, I encounter problems setting breakpoints with the default full stop mode in GDB. If the Zookeeper thread cannot be started, the server will delay the session and thus remove any ephemeral knowledge you might have created. In non-stop mode, I can prevent this, but I lose the convenience of checking the status of any stream without Zookeeper.

Is there a way in GDB to indicate that one (or more) threads will continue to work in the application when a breakpoint is hit, but the rest will stop working? That way, I can check the status of the threads I care about and ignore the status of those I want to run in the background.

Edit: this essentially duplicate does not stop all threads in gdb . The decision there to use the background commands in non-stop mode substantially solves my problem, since I can stop the threads and restart them asynchronously whenever I want, so maybe we should close this one.

+4
source share
3 answers

In Zookeeper it turns out that you can perform a hack to continue the session, interrupting in gdb. This hack uses several properties of Zookeeper and gdb:

  • You may have multiple Zookeeper clients with the same session ID
  • gdb does not stop child processes at parent breakpoints
  • You can ignore gdb signals in the child process without affecting the parent

Based on this, the solution becomes a child process that connects to Zookeeper with the same client ID as the parent, and does nothing. However, Zookeeper clients have an idea of โ€‹โ€‹moving a session, where each client so often switches the server to which they are connected. If you have two clients with the same session ID, one of them can move, leaving the other connected to a server that is not conducting its session. To prevent this, the child node should only connect to the server to which the parent is currently connected. Thus, the parent and child elements are as follows:

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 with libzookeeper_mt-0.3.3 and it works as described. Some nastiness starts to erupt from Zookeeper magazines when you make this hack that can be frustrating. If you cannot ignore the logs, you can disable them as follows:

 zoo_set_debug_level((ZooLogLevel)0); 

This is an undocumented way in Zookeeper to turn off logging.

0
source

It helps:

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

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

0
source

You can set flow-dependent 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. 
0
source

Source: https://habr.com/ru/post/1343051/


All Articles