控制執行緒執行作業

使用 zxdb 時,您可以控制執行緒的執行作業,協助您進行偵錯。偵錯時,您可以使用下列項目控制執行作業:

  • 執行緒

    執行緒是程序中的執行單位。代表可獨立執行的單一指令序列。

    如要在 zxdb 中透過執行緒控制執行作業,請參閱「執行緒」。

  • 堆疊框架

    堆疊框架是呼叫函式時配置的呼叫堆疊區段。當中儲存函式執行所需的資訊,例如:

    • 區域變數:在函式中宣告的變數。
    • 參數:傳遞至函式的值。
    • 回傳位址:函式完成後要返回的程式碼位置。

    如要在 zxdb 中透過堆疊框架控制執行作業,請參閱「堆疊框架」。

執行緒

在 zxdb 中,thread 是可與 zxdb 動詞搭配使用的名詞

如要列出目前程序中的執行緒:

thread
  # State   Koid Name
▶ 1 Blocked 1323 initial-thread
  2 Running 3462 worker-thread

在某些情況下,您可能會發現執行緒標示為 Blocked,表示執行緒在系統呼叫時停止。通常在偵錯非同步應用程式時,這也可能表示等待時間。

執行緒控制指令僅適用於暫停的執行緒,不適用於遭封鎖或執行的執行緒。暫停執行緒的方法有很多種:

pause 執行緒

舉例來說,如要使用 pause 指令暫停執行緒 2

thread 2 pause
🛑 syscalls-x86-64.S:67
   65 m_syscall zx_port_create 60 2 1
   66 m_syscall zx_port_queue 61 2 1
 ▶ 67 m_syscall zx_port_wait 62 3 0
   68 m_syscall zx_port_cancel 63 3 1
   69 m_syscall zx_timer_create 64 3 1

當執行緒暫停時,zxdb 會顯示目前的原始碼位置。如果執行緒處於系統呼叫中 (如上述範例),原始碼位置會解析為產生系統呼叫的組合語言巨集檔案中的位置。

如果您在執行 pause 時沒有提供任何額外背景資訊,zxdb 會暫停目前附加的所有程序的所有執行緒。

例如:

pause
   508                 const zx_port_packet_t* packet))
   509
 ▶ 510 BLOCKING_SYSCALL(port_wait, zx_status_t, /* no attributes */, 3, (handle, deadline, packet),
   511                  (_ZX_SYSCALL_ANNO(use_handle("Fuchsia")) zx_handle_t handle, zx_time_t deadline,
   512                   zx_port_packet_t* packet))
🛑 $elf(SYSCALL_zx_port_wait) + 0x7 • syscalls.inc:510

continue 執行緒

暫停執行緒並開始偵錯問題後,您可能想要continue執行緒。繼續執行表示恢復執行作業,直到程式正常完成為止。

舉例來說,如要 continue 執行執行緒 1

thread 1 continue

如果您在執行 continue 時未提供任何額外內容,zxdb 會繼續執行所有附加程序的所有執行緒。

例如:

continue

逐步執行執行緒

暫停執行緒後,您可以控制執行緒的執行作業。你可以使用下列任一指令:

  • finish (fi)

    結束函式,並在呼叫後立即停止。

    finish
    
  • next (n)

    前進至下一行,略過函式呼叫。

    next
    
  • nexti

    前進至下一個指令,但略過目標架構的呼叫指令。

    nexti
    
  • ss

    列出目前行上的函式呼叫,並逐步執行所選呼叫。系統會自動結束先接聽的通話。

    ss
      1 std::string::string
      2 MyClass::MyClass
      3 HelperFunctionCall
      4 MyClass::~MyClass
      5 std::string::~string
      quit
    >
    
  • step (s)

    前進至下一行程式碼。如果函式呼叫發生在下一行之前,系統會進入該函式,並在函式開頭停止執行。

    您也可以提供引數子字串,比對特定函式呼叫。系統會略過不含引數子字串的函式名稱,並只逐步執行相符的函式。

    step
    [zxdb] step MyFunction
    
  • stepi

    正好前進一個機器指令。

    stepi
    
  • until (u)

    指定行位置後,繼續執行執行緒,直到抵達該位置為止。舉例來說,如要執行到目前檔案的第 45 行,請輸入:

    until 45
    

    您也可以執行程式,直到執行作業返回指定的堆疊框架為止:

    frame 2 until
    

堆疊框架

堆疊框架是函式呼叫。當函式呼叫另一個函式時,系統會建立新的影格。列出執行緒的影格會傳回呼叫堆疊。

如要列出目前執行緒中的堆疊框架:

frame
▶ 0 fxl::CommandLineFromIterators<const char *const *>() • command_line.h:203
  1 fxl::CommandLineFromArgcArgv() • command_line.h:224
  2 main() • main.cc:174

使用堆疊框架時,0 表示堆疊頂端,也就是執行作業的結尾。堆疊底部 (即堆疊影格編號最高的位置) 表示執行作業的開始。

您可以使用 updown 指令瀏覽影格清單。

舉例來說,使用 up 從目前的影格 0 導覽至影格 1

up
  1 fxl::CommandLineFromIterators<const char *const *>() • command_line.h:204

舉例來說,使用 down 從目前的影格 1 導覽至影格 0

[zxdb] down
  0 fxl::CommandLineFromIteratorsFindFirstPositionalArg<const char *const *>()  command_line.h:185

您也可以使用 frame 指令搭配影格編號,前往特定影格:

frame 1

詳情請參閱 backtrace

在某些情況下,您可能想查看堆疊框架未提供的額外位址資訊。backtrace 指令與 frame 相同,但會提供更詳細的地址資訊和函式參數。

如要列出目前執行緒中的堆疊框架,但提供更詳細的資訊,請使用 backtrace

backtrace
▶ 0 fxl::CommandLineFromIteratorsFindFirstPositionalArg<const char *const *>() • command_line.h:185
      IP = 0x10f982cf2ad0, BP = 0x66b45a01af50, SP = 0x66b45a01af38
      first = (const char* const*) 0x59f4e1268dc0
      last = (const char* const*) 0x59f4e1268dc8
      first_positional_arg = (const char* const**) 0x0
  1 fxl::CommandLineFromIterators<const char *const *>() • command_line.h:204
      IP = 0x10f982cf2ac0, BP = 0x66b45a01af50, SP = 0x66b45a01af40
      first = <'first' is not available at this address. >
      last = <'last' is not available at this address. >
...

使用 list 查看原始碼

每個堆疊框架都有程式碼位置。使用 list 指令查看原始碼。

您可以列出特定堆疊框架的指令指標周圍的程式碼。

舉例來說,如要 list 堆疊框架指令指標周圍的原始碼 3

frame 3 list

如果您在沒有內容的情況下使用 list,zxdb 會列出目前堆疊框架指令指標附近的原始碼:

list
   183 inline CommandLine CommandLineFromIteratorsFindFirstPositionalArg(
   184     InputIterator first, InputIterator last,
 ▶ 185     InputIterator* first_positional_arg) {
   186   if (first_positional_arg)
   187     *first_positional_arg = last;

list 的其他用途

此外,您可以使用 list 列出特定事項:

函式

使用 list 列出函式:

list MyClass::MyFunc

檔案

使用 list 列出特定檔案:

list --all myfile.cc:1

顯示行號的檔案

使用 list 列出特定檔案和特定行號:

list foo.cc:43