控制线程执行

使用 zxdb 时,您可以控制线程的执行以便进行调试。 在调试时,您可以使用以下工具来控制执行:

  • 线程

    线程是进程中的执行单元。它代表 可以单独执行的指令序列。

    要通过 zxdb 中的线程控制执行,请参阅线程

  • 堆栈帧

    堆栈帧是调用堆栈的一部分, 调用该方法。它会存储函数执行所需的信息,例如:

    • 局部变量:在函数中声明的变量。
    • 参数:传递给函数的值。
    • 返回地址:在代码中经过 函数完成。

    要通过 zxdb 中的堆栈帧控制执行,请参见 堆栈帧

线程

在 zxdb 中,thread 是可与 zxdb 搭配使用的名词 动词

如需列出当前进程中的线程,请执行以下操作:

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

在某些情况下,您可能会发现某个线程被标记为 Blocked,这意味着 表示线程在系统调用时停止。通常,当您 异步应用,这也可以指示等待时间。

线程控制命令仅适用于已暂停的线程,不适用于阻塞或正在运行的线程 线程。挂起线程有以下几种方法:

pause消息串

例如,如需使用 pause 命令挂起线程 2,请使用以下命令:

[zxdb] 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 会暂停 当前挂接的所有进程

例如:

[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

[zxdb] thread 1 continue

如果您在没有任何其他上下文的情况下运行 continue,zxdb 会继续 所有附加进程的线程。

例如:

[zxdb] continue

单步调试线程

线程暂停后,您可以控制其执行。您可以使用 命令:

  • finish (fi)

    退出函数并在调用后立即停止。

    [zxdb] finish
    
  • next (n)

    跳转至下一行,跳过函数调用。

    [zxdb] next
    
  • nexti

    前进到下一条说明,但跳过了通话说明中 目标架构。

    [zxdb] nexti
    
  • ss

    列出当前行上的函数调用,然后单步进入所选的调用。这个 自动完成最先发生的任何其他调用。

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

    前进到下一个代码行。如果函数调用发生在 该函数会单步进入,并在 该函数的开头。

    您还可以提供一个参数子字符串来匹配特定的函数调用。 系统会跳过不包含参数子字符串的函数名称, 只有匹配的函数会单步进入。

    [zxdb] step
    [zxdb] step MyFunction
    
  • stepi

    前进一个机器指令。

    [zxdb] stepi
    
  • until (u)

    给定代码行位置后,继续执行线程,直至执行到达该位置。对于 例如,运行到当前文件的第 45 行:

    [zxdb] until 45
    

    您也可以一直运行,直到执行返回到给定堆栈帧:

    [zxdb] frame 2 until
    

堆栈帧

堆栈帧是一种函数调用。当一个函数调用另一个函数时, 帧。列出线程的帧会返回调用堆栈。

如需列出当前线程中的堆栈帧,请执行以下操作:

[zxdb] 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

[zxdb] 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 命令和 帧号:

[zxdb] frame 1

使用 backtrace 了解更多详情

在某些情况下,您可能希望看到 堆栈帧所不具备的优点backtrace 命令与 frame 完全相同,但 可提供更详细的地址信息以及函数参数。

列出当前线程中的堆栈帧,但包含更详细的 信息,请使用 backtrace

[zxdb] 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

[zxdb] frame 3 list

在没有上下文的情况下使用 list 时,zxdb 会列出源代码 当前堆栈帧的指令指针周围:

[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 列出函数:

[zxdb] list MyClass::MyFunc

文件

使用 list 列出特定文件:

[zxdb] list --all myfile.cc:1

包含行号的文件

使用 list 可列出具有特定行号的特定文件:

[zxdb] list foo.cc:43