gdb的多线程调试

一些术语
all-stop mode      全停模式
single-stepping    单步执行
scheduler-locking  调度锁
schedule-multiple  多进程调度
record mode        记录模式
replay mode        回放模式

inferior
GDB用 inferior 来表示每一个程序执行,inferior 与进程对应,也可用于没有进程的target。
Inferiors在进程运行以前建立,在进程退出以后保留。Inferior 也有本身的标记,这个标记与PID不一样。
一般,每一个inferior都有本身的不一样地址空间,一些嵌入式 targets 能够在一个地址空间的不一样部分运行不一样的 inferior。
每一个 inferior 内能够有多个线程运行。

(gdb) info threads
(gdb) thread n
(gdb) set scheduler-locking [off|on|step]
(gdb) set schedule-multiple [off|on]
(gdb) show scheduler-locking
(gdb) show schedule-multiple

在开始以前先说一些技巧吧:
1  若是你在程序没运行前想设置 scheduler-locking 的状态,老是给出以下的提示:
   Target 'exec' cannot support this command.
   那你能够先在 main 函数处打个断点,break main ,等待运行后停在断点处,再执行你的设置。
   其实能够在任何断点停住的地方进行设置。

2  在线程的代码里设置了断点,那遇到断点全部的线程都会中止。且自动切换到断点所在线程。
   info threads 列出的线程列表里,当前线程前边有个 * 号。


5.5.1 All-Stop Mode

In all-stop mode,  whenever your program stops under GDB 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.

在全停模式下,当你的程序因为任何缘由在 GDB 下中止时,不止当前的线程中止,全部的执行线程都中止。这样容许你检查程
序的总体状态,包括线程之间的切换,不用担忧当下会有什么改变。

Conversely, whenever you restart the program,  all threads start executing.  This is true even when
single-stepping with commands like step or next.

相反,重启程序,全部的线程开始执行。即时使用像 step 或者 next 这样的单步命令,也是如此。

In particular,  GDB cannot single-step all threads in lockstep.  Since thread scheduling is  up  to
your debugging target’s operating system (not controlled by GDB),  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.

特别是,GDB 不能步调一致的单步执行全部线程。由于线程调度是操做系统负责的,当前线程完成一个单步额同时其它线程可能执行了
多个语句。此外,程序中止时,一般其它线程中止在语句的中间,而不是在一个清晰的语句边界,

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.

执行继续或者单步后,你甚至可能发现程序在另外一个线程中中止了,这个中止发生在第一个线程完成你的请求的任何操做以前(括号内为
我的理解,好比你请求了一个断点,就是说断点停住的时候全部线程已经中止了),每当有其它线程运行到一个断点,信号,或者特例。

Whenever GDB stops your program, due to a breakpoint or a  signal,  it  automatically  selects  the
thread where that breakpoint or signal happened.  GDB alerts you  to  the  context  switch  with  a
message such as ‘[Switching to Thread n]’ to identify the thread.

每当 GDB 中止程序,处理断点或者信号,它自动选择断点或者信号发生的线程。GDB 经过 “[Switching to Thread n]” 之类的
消息提醒上下文的切换,以标识线程。

On some OSes,  you can modify GDB’s default behavior by locking the OS scheduler to  allow  only  a
single thread to run.

在一些操做系统,能够经过锁定系统调度而只容许一个线程执行的方法修改 GDB 的默认习惯。

set scheduler-locking mode
Set the scheduler locking mode. It applies to normal execution, record mode, and replay mode. If it
is off, then there is no locking and any thread may run at any time.  If on,  then only the current
thread may run when the inferior is resumed.  The  step  mode  optimizes  for  single-stepping;  it
prevents other threads from preempting the current thread while you are stepping, so that the focus
of debugging does not change unexpectedly.  Other threads never get a chance to run when you  step,
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,  GDB does  not  change  the
current thread away from the thread that you are debugging.  The replay mode behaves  like  off  in
record mode and like on in replay mode.

设置调度锁模式。应用于正常执行,记录模式和回放模式。若是是 off ,那么不锁定,任何线程可在任什么时候间运行(可是一旦遇到断点,
全部的线程都会停住)。若是是 on ,仅当前线程在 inferior 被恢复(就是断点继续)时执行。step 模式优化单步执行;执行单步
调试时防止其它线程抢占当前线程,以便调试的焦点不会意外改变。执行单步(next或step)时其它线程没有机会运行,执行continue,
until, 或者 finish 后线程被彻底释放执行。可是,除非另外一个线程在时间片内击中断点,GDB 不离开当前正在调试的线程。回放
模式在记录模式下表现的像关闭,在回放模式下表现的像打开。

show scheduler-locking
Display the current scheduler locking mode.

显示当前的调度锁模式。

By default, when you issue one of the execution commands such as continue, next or step, GDB allows
only threads of the current inferior to run. For example, if GDB is attached to two inferiors, each
with two threads,  the continue command resumes only the two threads of the current inferior.  This
is useful, for example, when you debug a program that forks and you want to hold the parent stopped
(so that, for instance, it doesn’t run to exit),  while you debug the child.  In other  situations,
you may not be interested in inspecting the current state of any of the processes GDB  is  attached
to, and you may want to resume them all until some breakpoint is hit.  In the latter case,  you can
instruct GDB to allow all threads of all the  inferiors  to  run  with  the  set  schedule-multiple
command.

默认状况下,当你发出一个执行命令,如 continue, next, 或 step,GDB 仅容许当前 inferior 的线程运行。好比,若是 GDB
被依附到两个 inferior,每一个有2个线程,continue 仅恢复当前 inferior 的2个线程。这是有用的,好比,调试钩子程序,想停
止父进程(好比让它不运行就退出)当你调试子进程时。在其它状况下,你可能对被GDB依附的程序的当前状态不感兴趣,你可能想恢复所
有的进程,直到断点被击中。最后一种状况,你可使用 set schedule-multiple 命令,指示 GDB 容许全部 inferior 的全部
线程运行。

set schedule-multiple
Set the mode for allowing threads of multiple processes to be resumed when an execution command  is
issued. When on, all threads of all processes are allowed to run. When off, only the threads of the
current process are resumed.  The default is off.  The scheduler-locking mode takes precedence when
set to on, or while you are stepping and set to step.

设置当执行命令时(是否)容许多个进程的线程被恢复的模式。若是是 on ,全部进程的线程被容许执行。若是是 off ,仅当前进程的
线程被恢复。默认值是 off 。 scheduler-locking 模式设置为 on 时, 或者设置为 step 而且正在执行单步调试,这时
scheduler-locking 优先。

show schedule-multiple
Display the current mode for resuming the execution of threads of multiple processes.
显示用于恢复多进程线程执行的当前模式。
相关文章
相关标签/搜索