[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
5.4 Stopping and Starting Multi-thread Programs
When your program has multiple threads (see section Debugging Programs with Multiple Threads), you can choose whether to set breakpoints on all threads, or on a particular thread.
-
break linespec thread threadno
-
break linespec thread threadno if …
linespec specifies source lines; there are several ways of writing them, but the effect is always to specify some source line.
Use the qualifier ‘thread threadno’ with a breakpoint command to specify that you only want No value for GDBN to stop the program when a particular thread reaches this breakpoint. threadno is one of the numeric thread identifiers assigned by No value for GDBN, shown in the first column of the ‘info threads’ display.
If you do not specify ‘thread threadno’ when you set a breakpoint, the breakpoint applies to all threads of your program.
You can use the
thread
qualifier on conditional breakpoints as well; in this case, place ‘thread threadno’ before the breakpoint condition, like this:(No value for GDBP) break frik.c:13 thread 28 if bartab > lim
Whenever your program stops under No value for GDBN for any reason, all threads of execution stop, not just the current thread. This allows you to examine the overall state of the program, including switching between threads, without worrying that things may change underfoot.
There is an unfortunate side effect. If one thread stops for a breakpoint, or for some other reason, and another thread is blocked in a system call, then the system call may return prematurely. This is a consequence of the interaction between multiple threads and the signals that No value for GDBN uses to implement breakpoints and other events that stop execution.
To handle this problem, your program should check the return value of each system call and react appropriately. This is good programming style anyways.
For example, do not write code like this:
sleep (10); |
The call to sleep
will return early if a different thread stops
at a breakpoint or for some other reason.
Instead, write this:
int unslept = 10; while (unslept > 0) unslept = sleep (unslept); |
A system call is allowed to return early, so the system is still conforming to its specification. But No value for GDBN does cause your multi-threaded program to behave differently than it would without No value for GDBN.
Also, No value for GDBN uses internal breakpoints in the thread library to monitor certain events such as thread creation and thread destruction. When such an event happens, a system call in another thread may return prematurely, even though your program does not appear to stop.
Conversely, whenever you restart the program, all threads start
executing. This is true even when single-stepping with commands
like step
or next
.
In particular, No value for GDBN cannot single-step all threads in lockstep. Since thread scheduling is up to your debugging target's operating system (not controlled by No value for GDBN), other threads may execute more than one statement while the current thread completes a single step. Moreover, in general other threads stop in the middle of a statement, rather than at a clean statement boundary, when the program stops.
You might even find your program stopped in another thread after continuing or even single-stepping. This happens whenever some other thread runs into a breakpoint, a signal, or an exception before the first thread completes whatever you requested.
On some OSes, you can lock the OS scheduler and thus allow only a single thread to run.
-
set scheduler-locking mode
-
Set the scheduler locking mode. If it is
off
, then there is no locking and any thread may run at any time. Ifon
, then only the current thread may run when the inferior is resumed. Thestep
mode optimizes for single-stepping. It stops other threads from “seizing the prompt” by preempting the current thread while you are stepping. Other threads will only rarely (or never) get a chance to run when you step. They are more likely to run when you ‘next’ over a function call, and they are completely free to run when you use commands like ‘continue’, ‘until’, or ‘finish’. However, unless another thread hits a breakpoint during its timeslice, they will never steal the No value for GDBN prompt away from the thread that you are debugging. -
show scheduler-locking
Display the current scheduler locking mode.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |