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.
顯示用於恢復多進程線程執行的當前模式。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM