17

I'm a little new to GDB. I'm hoping someone can help me with something that should be quite simple, I've used Google/docs but I'm just missing something.

What is the 'normal' way folks debug threaded apps with GDB? I'm using pthreads. I'm wanting to watch only one thread - the two options I see are

a) tell the debugger somehow to attach to a particular thread, such that stepping wont result in jumping threads on each context switch

b) tell the debugger to suspend/free any 'uninteresting' threads

I'd prefer to go route b) - reading the help for GDB I dont see a command for this, tips?

stuck
  • 2,264
  • 2
  • 28
  • 62

2 Answers2

15

See documentation for set scheduler-locking on.

Beware: if you suspend other threads, and if one of them holds a lock, and if your interesting thread needs that lock at some point while stepping, you'll deadlock.

What is the 'normal' way folks debug threaded apps

You can never debug thread correctness, you can only design it in. In my experience, most of debugging of threaded apps is putting in assertions, and examining state of the world when one of the assertions is violated.

Employed Russian
  • 199,314
  • 34
  • 295
  • 362
  • by "normal" I ment more of a frequency of technique question than a "how-to" on threaded programming. on Windows I usually see folks freezing out one or two threads that they want to ignore while focusing on a particular thread. the 'set scheduler-locking on' technique is kind of opposite – stuck Apr 18 '11 at 00:06
  • 2
    is there a way to freeze out just one thread? I only see options for off/on – stuck Apr 18 '11 at 00:07
  • To add to Employed Russian's answer. The key to multi threaded programming is to avoid it as much as possible. Only expose the smallest amount of code you can and you have a chance of getting it right and being able to to analyze it properly and review it as a confined bit of code. – David Bradley Jul 31 '22 at 20:44
13

First, you need to enable comfortable for multi-threading debugger behavior with the following commands. No idea why it's disabled by default.

set target-async 1
set non-stop on

I personally put those commands into .gdbinit file. They make your every command to be applied only to the currently focused thread. Note: the thread might be running, so you have to pause it.

To see the focused thread execute the thread.

To switch to another thread append the number of the thread, e.g. thread 2.

To see all threads with their numbers issue info thread.

To apply a command to a particular thread issue something like thread apply threadnum command. E.g. thread apply 4 bt will apply backtrace command to a thread number 4. thread apply all continue continues all paused threads.

There is a small problem though — many commands needs the thread to be paused. I know a few ways of doing that:

  • interrupt command: interrupts the thread execution, accepts a number of a thread to pause, without an argument breaks the focused one.
  • Setting a breakpoint somewhere. Note that you may set a breakpoint to a particular thread, so that other threads will ignore it, like break linenum thread threadnum. E.g. break 25 thread 4.

You may also find very useful that you can set a list of commands to be executed when a breakpoint hit through the command commands — so e.g. you may quickly print interesting values, then continue execution.

Hi-Angel
  • 4,933
  • 8
  • 63
  • 86
  • Thanks for the tips. I also found in multi-thread program using conditional breakpoint with complex expression such as `b func if arg1->foo().bar().c_str() == "xxx" `is very weird. Have you ever used this technique ? – Lewis Chan Feb 19 '20 at 02:21
  • Oh, tbh I didn't even know you can put `if condition` inside `break` command. I used to first execute `break somewhere`, and then execute `commands`, where I write down the if-condition. Thanks for the tip! ;) – Hi-Angel Feb 19 '20 at 08:47